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

New Timers #151

Open
Rahix opened this issue Mar 3, 2021 · 4 comments
Open

New Timers #151

Rahix opened this issue Mar 3, 2021 · 4 comments
Labels
hal-api API design for the different components of avr-hal hal-generic Related to MCU generic parts of avr-hal
Milestone

Comments

@Rahix
Copy link
Owner

Rahix commented Mar 3, 2021

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:

  • PWM for LED Brightness
  • PWM for Servo Control
  • Time-Keeping a la millis()
  • Waveform with variable frequency, e.g. sound output
  • Phase-correct PWM for motor drivers

Cc: @koutoftimer

@Rahix Rahix added hal-api API design for the different components of avr-hal hal-generic Related to MCU generic parts of avr-hal labels Mar 3, 2021
@Rahix Rahix added this to the New APIs milestone Mar 3, 2021
@andrewshadura
Copy link

  • Waveform generation using the CTC mode.

@mutantbob
Copy link
Contributor

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.

@mutantbob
Copy link
Contributor

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.

@mutantbob
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hal-api API design for the different components of avr-hal hal-generic Related to MCU generic parts of avr-hal
Projects
None yet
Development

No branches or pull requests

3 participants