Skip to content

Add a non busy sleep #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
54 changes: 49 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ pin-utils = "0.1.0"
futures-util = { version = "0.3.5", default-features = false, features = ["async-await-macro"] }
ufmt = "0.1.0"

[dependencies.arduino-hal]
git = "https://github.com/rahix/avr-hal"
rev = "f84c0dff774c2292bc932b670955165161ecc7d1"
features = ["arduino-uno"]

[profile.dev]
panic = "abort"
lto = true
Expand Down
59 changes: 59 additions & 0 deletions examples/timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! This example demonstrates how to set up a SPI interface and communicate
//! over it. The physical hardware configuation consists of connecting a
//! jumper directly from pin `~11` to pin `~12`.
//!
//! This example opens a serial connection to the host computer. On most POSIX operating systems (like GNU/Linux or
//! OSX), you can interface with the program by running (assuming the device appears as ttyACM0)
//!
//! $ sudo screen /dev/ttyACM0 57600#

#![no_std]
#![no_main]
#![feature(abi_avr_interrupt)]

use panic_halt as _;
use core::cell::RefCell;
use avr_hal_generic::void::ResultVoidExt;

use async_avr::timer::TimeReader;

use async_avr::{block_on, timer};

struct ArduinoOneHwTimer {
timer: arduino_hal::pac::TC1,
}

impl timer::TimeReader for ArduinoOneHwTimer {
fn ticks(&self) -> u16 {
return self.timer.tcnt1.read().bits();
}
}

#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 9600);

let mut led = pins.d13.into_output();

dp.TC1.tccr1b.write(|w| w.cs1().prescale_1024());
let hw_timer = RefCell::new(ArduinoOneHwTimer { timer: dp.TC1 });

let led_blink_1s = async {
loop {
led.toggle();
timer::Timer::sleep_in_millis(1000u16, hw_timer.borrow()).await;
}
};

let serial_write_3_5s = async {
loop {
ufmt::uwriteln!(&mut serial, "Another 3.5s have passed! {}\r", hw_timer.borrow().ticks()).void_unwrap();
timer::Timer::sleep_in_millis(3500u16, hw_timer.borrow()).await;
}
};

block_on(async { futures_util::join!(led_blink_1s, serial_write_3_5s) });
loop {}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub use executor::block_on;
use futures_util::future::Future;
pub use spi::AsyncSpi;

pub mod timer;

pub struct AsyncSerial<T>(T);

impl<T> AsyncSerial<T> {
Expand Down
37 changes: 37 additions & 0 deletions src/timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use core::cell::Ref;
use core::task::{Context, Poll};

pub trait TimeReader {
fn ticks(&self) -> u16;
}

pub struct Timer<'a, T> where T: TimeReader {
delay_in_ticks: u16,
start_tick: u16,
hw_timer: Ref<'a, T>,
}

impl<'a, T: TimeReader> Timer<'a, T> {
pub fn sleep_in_millis(delay_in_millis: u16, hw_timer: Ref<'a, T>) -> Timer<'a, T> {
Timer {
// this assumes a 16MHz timer with a 1024 prescalar
delay_in_ticks: delay_in_millis * 10 / 64u16 * 100,
start_tick: hw_timer.ticks(),
hw_timer: hw_timer
}
}
}

impl<'a, T: TimeReader> crate::Future for Timer<'a, T> {
type Output = bool;

fn poll(self: crate::Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
let tick = self.hw_timer.ticks();

if tick - self.start_tick >= self.delay_in_ticks {
return Poll::Ready(true);
} else {
return Poll::Pending;
}
}
}