Skip to content
This repository has been archived by the owner on May 15, 2021. It is now read-only.

Timers #12

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 56 additions & 78 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,60 @@
//! Delays

use cast::u32;
use nrf51::TIMER0;

use nrf51::{TIMER0, TIMER1, TIMER2, RTC0, RTC1};
use hal::blocking::delay::{DelayMs, DelayUs};

/// System timer `TIMER0` as a delay provider
pub struct Delay {
timer: TIMER0,
}

impl Delay {
/// Configures the TIMER0 as a delay provider
pub fn new(timer: TIMER0) -> Self {
timer.tasks_stop.write(|w| unsafe { w.bits(1) });

// Set counter to 24bit mode
timer.bitmode.write(|w| unsafe { w.bits(2) });

// Set prescaler to 4 == 1MHz timer
timer.prescaler.write(|w| unsafe { w.bits(4) });

Delay { timer }
}

pub fn free(self) -> TIMER0 {
self.timer
}
}

impl DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
self.delay_us(ms * 1_000);
}
}

impl DelayMs<u16> for Delay {
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32(ms));
}
}

impl DelayMs<u8> for Delay {
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32(ms));
}
}

impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
/* Clear event in case it was used before */
self.timer.events_compare[0].write(|w| unsafe { w.bits(0) });

/* Program counter compare register with value */
self.timer.cc[0].write(|w| unsafe { w.bits(us) });

/* Clear current counter value */
self.timer.tasks_clear.write(|w| unsafe { w.bits(1) });

/* Start counting */
self.timer.tasks_start.write(|w| unsafe { w.bits(1) });

/* Busy wait for event to happen */
while self.timer.events_compare[0].read().bits() == 0 {}

/* Stop counting */
self.timer.tasks_stop.write(|w| unsafe { w.bits(1) });
}
}

impl DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
self.delay_us(u32(us))
}
}

impl DelayUs<u8> for Delay {
fn delay_us(&mut self, us: u8) {
self.delay_us(u32(us))
}
}
pub use timer::{Timer, TimerCounter};
pub use timer::{Micros, Millis, Hertz};

pub type Delay<TIM> = Timer<TIM>;

macro_rules! delay {
( $($TIM:ty),+ ) => {
$(

impl DelayMs<u32> for Timer<$TIM> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you've renamed Delay to Timer? That'll break all some stuff, including your own examples in microbit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create an alias to Delay as a structural fix, as that what clients will expect. Behind the scenes though it makes no sense to have a distinction.

fn delay_ms(&mut self, ms: u32) {
self.delay_us(ms * 1_000);
}
}

impl DelayMs<u16> for Timer<$TIM> {
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32::from(ms));
}
}

impl DelayMs<u8> for Timer<$TIM> {
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32::from(ms));
}
}

impl DelayUs<u32> for Timer<$TIM> {
fn delay_us(&mut self, us: u32) {

let compare: u32 = Micros(u64::from(us))
.checked_mul(self.frequency())
.expect("Invalid delay time: {}μs");

self.delay(0, compare).unwrap();
}
}

impl DelayUs<u16> for Timer<$TIM> {
fn delay_us(&mut self, us: u16) {
self.delay_us(u32::from(us))
}
}

impl DelayUs<u8> for Timer<$TIM> {
fn delay_us(&mut self, us: u8) {
self.delay_us(u32::from(us))
}
}

)+
};
}

delay!(TIMER0, TIMER1, TIMER2, RTC0, RTC1);
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![cfg_attr(feature = "rt", feature(global_asm))]
#![feature(const_fn)]
#![allow(non_camel_case_types)]

extern crate cast;
Expand Down
Loading