Implement special register access mode to write to AVR protected registers #784
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The newer AVR Attiny chips contain a mechanism Microchip calls CCP: Configuration Change Protection.
There are a few special registers that configure system-level peripherals like the clock- or the flash-controller which should not be modified by accident. To prevent that, a special unlock byte has to be written to the CCP unlock register and then the protected register has to be written within the next four executed instructions. See chapter 8.5.7 on page 56 on the linked datasheet for more details.
I tried doing this using the regular register access mechanisms, but the rust compiler always reordered and optimized code so that this didn't work out. Even if it would have, it wouldn't be exactly reliable.
This patch adds a new Target type for AVRs and if it's selected the new file
generic_avr_ccp.rs
is emitted when generating code. This file contains a bunch of traits to define an unlock register, protected registers and blanket implementations that implement protected writes in case a register implements the aforementioned marker traits.This has to be used in conjunction with atdf2svd to get an SVD. After generating the pac, you still need to manually define the list of protected registers like this:
I have not found a way yet to figure out the information that a register is protected by using the ATDF/SVD.
There will be a follow-up PR on avr-device which uses svd2rust to generate PACs for all kinds of AVR devices. I added support for the attiny817 which depends on this new CCP register access code.
As soon as I submitted that PR, I'll cross-reference it.
I am open to suggestions on how to make the code nicer. Especially the parts written in assembler. It was very finicky to make this work and I am still not 100% satisfied with how it looks. I tried getting rid of the
ldi
instruction, but couldn't make it work.