Open Rahix opened 3 years ago
Is there an API that translates from the data sheet to the register writes? Right now I have code that does
tmr1.tccr1a.write(|w| w.wgm1().bits(0b00));
tmr1.tccr1b.write(|w| {
w.cs1()
//.prescale_256()
.variant(CLOCK_SOURCE)
.wgm1()
.bits(0b01)
});
tmr1.ocr1a.write(|w| unsafe { w.bits(ticks) });
tmr1.timsk1.write(|w| w.ocie1a().set_bit()); //enable this specific interrupt
It would probably be more readable if it looked like
let timer1 = Timer::wrap(dp.TC1);
timer1.set_clock_select(CS1_A::PRESCALE_256);
timer1.set_waveform_generation_mode(WaveformGenerationMode::CTC_OCR1A);
timer1.set_output_compare_register_1a(ticks);
timer1.set_output_compare_a_match_interrupt_enable(true);
or maybe
let timer1 = Timer::configure_and_enable_timer(
&dp.TC1,
CS1_A::PRESCALE_256,
WaveformGenerationMode::CTC_OCR1A,
ticks,
);
Although I am certain that the example code I provided drastically oversimplifies the options.
I assume this code will look a little different for each AVR implementation unless they all have the same register layout.
A quick review of the datasheets for the atmega328p (https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf) and the atmega2560(https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf) shows:
328p: 8-bit timer (TC0, section 14.9) 16-bit timer ( TC1, section 15.11 ) 8-bit timer w/ async-op (TC2, section 17.11 )
2560: 8-bit timers (TC0, section 16.9) 16-bit timers (TC1,3,4,5, section 17.11 ) 8-bit timer w/ async-op (TC2, section 20.10 )
When comparing the registers on the 328p and the 2560 one thing that jumps out is that the 2560 has A, B, and C (section 17.11.17-28) comparators on its 16-bit timers, while the 328p only has A and B (section 15.11.5&6).
I was hoping that the two models could be unified by some traits, but it will not be as clean as I initially hoped. I'm also unsure how this timer architecture generalizes across the other AVR implementations.
I have created a couple of timer experiments that I hope to turn into examples for the avr-hal project:
https://github.com/mutantbob/avr-timer/blob/master/led-pwm/src/megalovania.rs uses PWM and a buzzer to play a chiptune
https://github.com/mutantbob/avr-timer/blob/master/led-pwm/src/led-pwm.rs uses PWM with a duty cycle to control LED brightness.
If these apps are suitable use cases for the arduino-uno examples, let me know what changes are needed to bring them to their final form. It is also possible that they can serve as uses cases to drive a more friendly timer API.
This issue serves to track efforts on re-designing the timer API as part of #130. As a first step, I think we should gather a list of "use-cases" that should be supported:
millis()
Cc: @koutoftimer