ATtiny xy2: Missing #else path may lead to inconsistencies in core digital_pin_to_timer[] array

Open Beginner friendly
#1,294 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
arduino, c
Domain
cli, devtools

Research direction

The bug is in the digital_pin_to_timer[] array in variants/txy2/pins_arduino.h, where the #if defined(_TCA_ALT_WO0) / #elif defined(USE_TIMERD0_PWM) block for PA7 has no #else branch, so the array loses an element when neither macro is set. Start by reading that block and comparing it with the matching arrays in the other variant pins files. The fix is to add a matching #else entry, then confirm with avr-objdump that the array has six elements and that PA3 maps to TIMERA0 in a default-off build.

Written by the indexing model from the issue text.

Description

Hello,

I tried to setup some PWM output on Pin PA3 via analogWrite() on a ATTiny402 / ATTiny412 uC, but could not get it to work properly. The output only turned on for duty cycle values > 127, and stayed off otherwise.

After some debugging and tracing through the analogWrite() implementation, I noticed that for my setup (megaTinyCore 2.6.11 on PlatformIO / pioarduino), the timer assignment for pin PA3 (via the auto-populated digital_pin_to_timer[] array) indicates NOT_ON_TIMER, not the expected TIMERA0, matching the missing PWM functionality.
Even worse, the digital_pin_to_timer[] array has less elements than expected. While all other pin-related arrays have the required NUM_DIGITAL_PINS = 6 elements, digital_pin_to_timer[] is missing one entry:

From avr-objdump:

0000863a <digital_pin_to_timer>:
    863a:	00 10 10 10 00

0000863f <digital_pin_to_bit_position>:
    863f:	06 07 01 02 03 00

00008645 <digital_pin_to_port>:
    8645:	00 00 00 00 00 00

Root cause for the size and value mismatch seems to be a missing #else path in the digital_pin_to_timer[] setup:

From variants/txy2/pins_arduino.h, lines 189-210:

const uint8_t digital_pin_to_timer[] = {
  #if defined(DAC0) && !(defined(USE_TIMERD0_PWM) && defined(TCD0))
    DACOUT,       // 0  PA6
  #elif defined(USE_TIMERD0_PWM) && defined(TCD0)
    TIMERD0,
  #else
    NOT_ON_TIMER, // 0  PA6
  #endif
  #if defined(_TCA_ALT_WO0)
    TIMERA0,    // 1  PA7
  #elif defined(USE_TIMERD0_PWM)
    TIMERD0,
    // <--- Missing #else path
  #endif
  TIMERA0,      // 2  PA1
  TIMERA0,      // 3  PA2
  #if !defined(TCA_BUFFERED_3PIN)
    TIMERA0,      // 4  PA3
  #else
    NOT_ON_TIMER, // 4  PA3
  #endif
  NOT_ON_TIMER  // 5  PA0
};

If neither _TCA_ALT_WO0 nor USE_TIMERD0_PWM are defined, no element is inserted for pin PA7, leading to the off-by-one size and wrong value assignments for PA0-PA3. Adding that #else path results in a proper digital_pin_to_timer[] array and a working PWM output on PA3:

0000863a <digital_pin_to_timer>:
    863a:	00 00 10 10 10 00

PS:
I'm aware that if using ArduinoIDE, _TCA_ALT_WO0 is defined via -DTCA_PORTMUX=0x01 in the default board setup, and this issue may not be relevant. But maybe it helps other people using PlatformIO or a non-default setup. 😊

Dominant language
C
Stars
690
Forks
162
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from SpenceKonde/megaTinyCore

All issues in SpenceKonde/megaTinyCore

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.