Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No ctc function for atmega328p's WGM1_W #96

Open
Cryptjar opened this issue Apr 18, 2022 · 7 comments
Open

No ctc function for atmega328p's WGM1_W #96

Cryptjar opened this issue Apr 18, 2022 · 7 comments

Comments

@Cryptjar
Copy link

I'm a bit puzzled, why is there no ctc function on atmega328p::tc1::tccr1a::WGM1_W, as it is the case for WGM0_W and WGM2_W?

This inconsistency came up while I was working on Rahix/avr-hal#257. Not having this or a comparable function makes it hard to use timers in a generic way.

@Rahix
Copy link
Owner

Rahix commented Apr 22, 2022

This is usually an inconsistency in the vendor-provided ATDF files. We have infrastructure here in avr-device to fix such things - check the existing patches in https://github.com/Rahix/avr-device/tree/main/patch. Docs for the patch format can be found here: https://github.com/stm32-rs/svdtools#device-and-peripheral-yaml-format

Whenever you encounter such inconsistencies, please feel free to send a PR here with a fix :)

@Rahix Rahix added the bug Something isn't working label Apr 22, 2022
@Cryptjar
Copy link
Author

Hmm, I'm trying to wrap my head around this ATDF stuff. If I understand it correctly, the "vendor" only defines the WGMn fields, e.g. for TC0:

<bitfield caption="Waveform Generation Mode" mask="0x03" name="WGM0"/>

and

<bitfield caption="" mask="0x08" name="WGM02"/>

Then, the patch files define an enum on them (or seemingly only on WGM0):

WGM?:
_replace_enum:
NORMAL_TOP: [0, "Normal, Top: `0xff`, Update: *Immediate*, Flag: *MAX*"]
PWM_PHASE: [1, "Phase Correct PWM, Top: `0xff`, Update: *TOP*, Flag: *BOTTOM*"]
CTC: [2, "CTC, Top: *OCRA*, Update: *Immediate*, Flag: *MAX*"]
PWM_FAST: [3, "Fast PWM, Top: `0xff`, Update: *TOP*, Flag: *MAX*"]

And from that enum the ctc function, seems to be generated.

However, this data sheet of the atmega328p defines in Table 14-8 on page 86 that CTC is 0b010 combining WGM02 with WGM0. So it seems to me that the ctc function only sets the lower two bits of that, and if it happens that WGM02 was previously set to 1, calling ctc would yield the reserved state 0b110. Which seems rather wrong to me.

According to the data sheet, it gets even more complex with the TC1 because there are four bits and two CTC modes.

Thus, it seems that it would be more appropriate to have a ctc that can actually access both TCCRnA and TCCRnB. However, it seems to me that this is quite atypical compared to the rest of the avr-device API, and I have no clue how to express this kind in the patching YAML files (if it is even possible).

@Rahix
Copy link
Owner

Rahix commented Apr 27, 2022

Ah, you got it and now I also remember: We didn't add enum-values for this timer precisely because of the split bit-field. There is no way to represent this in SVD so code unfortunately has to manually set the bit-values for these timers...

@Rahix
Copy link
Owner

Rahix commented Apr 27, 2022

Actually, this can be seen, for example, in the old PWM implementation. There, a setup function had to be defined manually for each timer. Compare

https://github.com/Rahix/avr-hal/blob/ce52c90d3950cd81090627e3ad8494a15e4c8f66/chips/atmega328p-hal/src/pwm.rs#L48

with

https://github.com/Rahix/avr-hal/blob/ce52c90d3950cd81090627e3ad8494a15e4c8f66/chips/atmega328p-hal/src/pwm.rs#L95-L97

I don't think there are really any other options than doing it this way :/ Maybe enough timers are similar enough to create some macro-magic to reduce code-duplication but then this would of course make it much harder to understand... So I'm not sure if that would be worth it.

@Rahix Rahix removed the bug Something isn't working label Apr 27, 2022
@dalpil
Copy link
Contributor

dalpil commented May 28, 2022

I guess one could also argue for the removal of the COM?? and WGM?patches altogether, since they omit some of the timer modes due to the split WGM bitfield (as pointed out by Cryptjar) and obscure the settings of the mode-dependant (normal/fast/phase-correct/et.c.) COM??-registers.

Setting COM?? to 0b01 doesn't always mean "match_toggle" for example, since it depends on what mode the timer is in (as pointed out by the patch itself).

That being said -- it sure is convenient to have human-readable settings for some of this stuff, but it seems to me like the abstractions necessary to cover all the different combinations of modes and settings in a user-friendly way is something that maybe belongs in avr-hal rather than in avr-device(?).

These are just speculations from my part, as I haven't really dug into avr-device that much, but it did cause a bit of confusion on my part whilst playing around with different PWM generation modes on the atmega328p and attiny85, and in the end I opted for the .bits() method for setting the registers, to avoid confusion.

@Rahix
Copy link
Owner

Rahix commented Jun 4, 2022

It's a difficult decision to make... I completely agree that a proper abstraction on top is needed and it should go into avr-hal, not here. Using .bits() is the right interface to use.

However, when looking at the original PWM abstraction, we did leverage the enumerated value names for some of the timers, so I think there is value in keeping them... I am not sure to what degree though, because as you mentioned, sometimes the existing ones are actually wrong, too...

@Cryptjar
Copy link
Author

Cryptjar commented Jun 5, 2022

Ok, I added clearing the top bit for 8-bit timers:

https://github.com/Cryptjar/avr-hal/blob/dcfde7d59405f0acaaf1f945ad2bc8ef6a157333/avr-hal-generic/src/time.rs#L278-L288

and configured 16-bit timers by setting the raw bits:

https://github.com/Cryptjar/avr-hal/blob/dcfde7d59405f0acaaf1f945ad2bc8ef6a157333/avr-hal-generic/src/time.rs#L369-L379

Thus, I no longer consider this issue a blocker for Rahix/avr-hal#257

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants