use hal::blocking::delay;
use core::marker;
pub struct Delay<SPEED> {
_speed: marker::PhantomData<SPEED>,
}
impl<SPEED> Delay<SPEED> {
pub fn new() -> Delay<SPEED> {
Delay { _speed: marker::PhantomData }
}
}
pub struct MHz24;
pub struct MHz20;
pub struct MHz16;
pub struct MHz12;
pub struct MHz8;
pub struct MHz1;
#[cfg(target_arch = "avr")]
#[allow(unused_assignments)]
fn busy_loop(mut us: u16) {
unsafe {
asm!("1: sbiw $0,1\n\tbrne 1b"
: "=w"(us)
: "0"(us)
:
: "volatile"
);
}
}
#[cfg(not(any(target_arch = "avr", feature = "docs")))]
fn busy_loop(_us: u16) {
sorry!(This library is made for avr and cannot be compiled for anything else!)
}
#[cfg(feature = "docs")]
fn busy_loop(_us: u16) {
unimplemented!("This library is made for avr and cannot be used for anything else!")
}
impl delay::DelayUs<u16> for Delay<MHz24> {
fn delay_us(&mut self, mut us: u16) {
if us == 0 {
return;
}
us *= 6;
us -= 5;
busy_loop(us);
}
}
impl delay::DelayUs<u16> for Delay<MHz20> {
fn delay_us(&mut self, mut us: u16) {
unsafe {
asm!("nop\nnop\nnop\nnop" :::: "volatile");
}
if us <= 1 {
return;
}
us = (us << 2) + us;
us -= 7;
busy_loop(us);
}
}
impl delay::DelayUs<u16> for Delay<MHz16> {
fn delay_us(&mut self, mut us: u16) {
if us <= 1 {
return;
}
us <<= 2;
us -= 5;
busy_loop(us);
}
}
impl delay::DelayUs<u16> for Delay<MHz12> {
fn delay_us(&mut self, mut us: u16) {
if us <= 1 {
return;
}
us = (us << 1) + us;
us -= 5;
busy_loop(us);
}
}
impl delay::DelayUs<u16> for Delay<MHz8> {
fn delay_us(&mut self, mut us: u16) {
if us <= 2 {
return;
}
us <<= 1;
us -= 4;
busy_loop(us);
}
}
impl delay::DelayUs<u16> for Delay<MHz1> {
fn delay_us(&mut self, mut us: u16) {
if us <= 16 {
return;
} if us <= 25 {
return;
}
us -= 22; us >>= 2;
busy_loop(us);
}
}
impl<SPEED> delay::DelayUs<u8> for Delay<SPEED>
where
Delay<SPEED>: delay::DelayUs<u16>,
{
fn delay_us(&mut self, us: u8) {
delay::DelayUs::<u16>::delay_us(self, us as u16);
}
}
impl<SPEED> delay::DelayUs<u32> for Delay<SPEED>
where
Delay<SPEED>: delay::DelayUs<u16>,
{
fn delay_us(&mut self, us: u32) {
for _ in 0..(us >> 12) {
delay::DelayUs::<u16>::delay_us(self, 0xfff);
}
}
}
impl<SPEED> delay::DelayMs<u16> for Delay<SPEED>
where
Delay<SPEED>: delay::DelayUs<u32>,
{
fn delay_ms(&mut self, ms: u16) {
delay::DelayUs::<u32>::delay_us(self, ms as u32 * 1000);
}
}