-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Description
This issue is to discuss the API of the machine.Timer class. There are currently 3 different version of Timer which don't have much in common:
esp8266:
# id must be -1, period is in milliseconds, mode is PERIODIC or ONE_SHOT
Timer(id, *, period, mode, callback) # constructor
Timer.init(*, period, mode, callback) # reinitialise all parameters
Timer.deinit() # stop the timer
cc3200/wipy:
# mode is PERIODIC, ONE_SHOT or PWM
Timer(id, mode, *, width=16) # constructor
Timer.init(mode, *, width=16) # reinitialise
Timer.deinit() # stop
# each timer has one or more channels
# each timer channel is associated with a specific IO pin (eg for PWM)
Timer.channel(*, freq, period, polarity, duty_cycle) # create channel assoc with TImer
TimerChannel.freq([freq]) # get/set
TimerChannel.period([period]) # get/set
TimerChannel.duty_cycle([duty]) # get/set
TimerChannel.irq(...) # get or set up the IRQ callback
stmhal/pyboard (actually pyb.Timer):
# freq is in Hz (can be float <1), prescaler/period are raw values, mode is UP/DOWN/CENTER
Timer(id, *, freq, prescaler, period, mode, div, callback, deadtime) # constructor
Timer.init(*, freq, prescaler, period, mode, div, callback, deadtime) # reinit
Timer.counter([value]) # get/set the raw timer counter
Timer.source_freq() # get source frequency that clocks this timer
Timer.freq([value]) # get/set
Timer.prescaler([value]) # get/set
Timer.period([value]) # get/set
Timer.callback(callable) # get/set callback (pass None to disable)
# each timer has multiple chanels (usually 4)
# pin is the pin to associate with the channel (eg for PWM)
Timer.channel(mode, *, callback, pin, pulse_width, pulse_width_percent, compare, polarity) # create
TimerChannel.pulse_width([value]) # get/set
TimerChannel.pulse_width_percent([value]) # get/set
TimerChannel.capture([value]) # get/set
TimerChannel.compare([value]) # get/set
TimerChannel.callback(callable) # get/set callback
To compare current usage, for a simple periodic timer at 10Hz one would do:
# esp8266
t = Timer(-1)
t.init(period=100, mode=Timer.PERIODIC, callback=lambda t:print(t))
# stmhal/pyboard
Timer(1, freq=10, callback=lambda t:print(t))
For a one-shot after 2 seconds:
# esp8266
t = Timer(-1)
t.init(period=2000, mode=Timer.ONE_SHOT, callback=lambda t:print(t))
# stmhal/pyboard
def cb(t):
print(t)
t.deinit() # or t.callback(None)
Timer(1, freq=0.5, callback=cb)
At the very least I'd suggest that all ports have the same interface to create periodic and one-shot timers, as well as the same way to configure the timer irq/callback. Configuration of the irq should follow the samy signature as machine.Pin.irq(); see also #2297.
I also feel that a timer should have start() and stop() methods, so that one can create an initialise a timer at one point in the code, then start it precisely when needed. This requires definining that the first callback happens one period after start() is called.