Skip to content

16-bit register writes in wrong order #132

Description

@alchitry

I'm working with an Attiny404 and was setting up PWM which requires writing to 16bit registers.

I was getting unexpected results when setting the PER and CMP1 registers (both 16bit).

I had code that looked like this.

dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.cmp1().write(|w| w.bits(100));

The PWM frequency would do really weird things. However, if I duplicate each line twice it worked as expected.

dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.cmp1().write(|w| w.bits(100));
dp.TCA0.cmp1().write(|w| w.bits(100));

I believe this is because the AVR requires you to write the upper register before writing the lower register. See https://ww1.microchip.com/downloads/en/Appnotes/doc1493.pdf

The opposite is true for reads (read low then high) so I assume reads are working.

This is my first into to Rust so I'm not exactly sure where to dive in to propose a fix for this. This may even be considered a compiler issue.

EDIT: Doing some experimenting it looks like the Attiny404 requires the low register to be written first. The same is true for reads. This is true for the new 0/1 series AVRs while the older "classic" mega and tiny required writes to be flipped.
https://microchip.my.site.com/s/article/Accessing-16-bit-registers-in-8-bit-AVR-devices

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions