Timer

The first API we’ll rediscover is Timer which deprecates the delay module.

Here’s an example of this API.

  1. #![deny(unsafe_code)]
  2. #![no_main]
  3. #![no_std]
  4. #[macro_use]
  5. extern crate pg;
  6. use core::iter;
  7. use pg::led::LEDS;
  8. use pg::{Async, Future, Timer};
  9. #[inline(never)]
  10. #[no_mangle]
  11. pub fn main() -> ! {
  12. let mut timer = Timer::new().unwrap();
  13. let mut periodic = timer.periodic(100);
  14. let mut leds = LEDS.iter()
  15. .zip(LEDS.iter().skip(1))
  16. .chain(iter::once((&LEDS[7], &LEDS[0])))
  17. .cycle();
  18. loop {
  19. if let Async::Ready(()) = periodic.poll() {
  20. if let Some((current, next)) = leds.next() {
  21. current.off();
  22. next.on();
  23. }
  24. }
  25. }
  26. }

The first thing you notice is that we need to create an instance of Timer tobe able to generate delays. Timer::new will create a unique instance of thetimer and thus will return Some only the first time is called; subsequentcalls of this constructor will return None. We’ll return to this requirementof uniqueness later on.

Timer provides a periodic method that returns an implementer of the Futuretrait: Periodic. Polling Periodic will return Async::Ready only after therequested timeout period, 500 milliseconds in this case, has elapsed.

Periodic also happens to be an “infinite stream” because it can yield aninfinite number of Async::Ready values.

Timer provides another method, oneshot. Which can be used to emulate the olddelay module. In fact, timer.oneshot(100).wait() is equivalent to thedelay::ms function because it also uses busy waiting to block for 100milliseconds.

The oneshot method actually returns a Future implementer, OneShot, whichcan be used in an asynchronous manner as well. This actually means that thisasynchronous API is a super set of the synchronous one because the synchronousbehavior can be easily achieved using the wait method.

Back to the issue of uniqueness. Timer uses the TIM7 peripheral under thehood. If we allowed creation of multiple instances of it, that would make codelike this compile:

  1. let mut timer1 = Timer::new();
  2. let mut timer2 = Timer::new();
  3. let delay1 = timer.oneshot(100);
  4. let delay2 = timer.oneshot(200);
  5. delay1.wait(); // this actually blocks for 200 milliseconds!

But this won’t work as expected because the second oneshot call will“overwrite” the previous oneshot call as both of these methods would endup writing to the same registers.