Closed agausmann closed 1 year ago
One example where this is useful: Adding a "debouncing delay" between detach and attach of USB pull resistors, where it doesn't really matter if the delay is 1ms or 16ms, and the user API is significantly simplified by not using timers or hal::Delay
.
Work in progress here: https://github.com/agausmann/atmega-usbd/pull/13
Based on the implementation of the same API in the nRF usb-device driver, which uses cortex_m::asm::delay
This could also be used to re-implement avr_hal_generic::Delay
for accurate delays up to ~250 seconds at 16 MHz (max counter value ~4 billion, divided by 16 MHz), which should be plenty for the majority of Delay
use cases
I am wondering whether we should just move the delay & clock code into avr-device
Yeah, that would also be a good idea.
I still think it would be useful to have a public cycle-based delay. Of course the documentation should have warnings and recommendations to use other APIs, which I did add.
In my case, the clock variation is really not a concern. Almost every scenario where you have USB, you are going to have a 16MHz oscillator due to the clock requirements of the USB (and therefore probably a 16MHz CPU clock, unless CKDIV8 fuse is enabled)
This is a counterpart to
cortex_m::asm::delay
but for AVR.It is intended for very simple delays in low-level drivers that don't require precision or real-time accuracy.
In those situations, it provides these benefits over the alternatives:
Compared to
Delay
from avr-hal, this dependency is more convenient; Sometimes it is not desired or not even possible to depend on avr-hal, and also the driver does not need to know the CPU clock frequency (if it doesn't care about 16x longer delays at 1MHz vs 16MHz).Compared to using hardware timers, this doesn't require ownership of any system resources, leaving more for the end user.