Use AtomicWaker instead of Signal

This commit is contained in:
Ulf Lilleengen 2021-10-19 15:31:28 +02:00
parent db3b315f94
commit c777b6aae1

View File

@ -6,11 +6,13 @@ use crate::peripherals::TEMP;
use core::future::Future; use core::future::Future;
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy::channel::signal::Signal; use core::task::Poll;
use embassy::interrupt::InterruptExt; use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::{drop::OnDrop, unborrow}; use embassy_hal_common::{drop::OnDrop, unborrow};
use fixed::types::I30F2; use fixed::types::I30F2;
use futures::future::poll_fn;
/// Integrated temperature sensor. /// Integrated temperature sensor.
pub struct Temp<'d> { pub struct Temp<'d> {
@ -18,7 +20,7 @@ pub struct Temp<'d> {
_irq: interrupt::TEMP, _irq: interrupt::TEMP,
} }
static IRQ: Signal<I30F2> = Signal::new(); static WAKER: AtomicWaker = AtomicWaker::new();
impl<'d> Temp<'d> { impl<'d> Temp<'d> {
pub fn new( pub fn new(
@ -27,16 +29,12 @@ impl<'d> Temp<'d> {
) -> Self { ) -> Self {
unborrow!(_t, irq); unborrow!(_t, irq);
let t = Self::regs();
// Enable interrupt that signals temperature values // Enable interrupt that signals temperature values
t.intenset.write(|w| w.datardy().set());
irq.disable(); irq.disable();
irq.set_handler(|_| { irq.set_handler(|_| {
let t = Self::regs(); let t = Self::regs();
t.events_datardy.reset(); t.intenclr.write(|w| w.datardy().clear());
let raw = t.temp.read().bits(); WAKER.wake();
IRQ.signal(I30F2::from_bits(raw as i32));
}); });
irq.enable(); irq.enable();
Self { Self {
@ -60,19 +58,26 @@ impl<'d> Temp<'d> {
// In case the future is dropped, stop the task and reset events. // In case the future is dropped, stop the task and reset events.
let on_drop = OnDrop::new(|| { let on_drop = OnDrop::new(|| {
let t = Self::regs(); let t = Self::regs();
unsafe { t.tasks_stop.write(|w| unsafe { w.bits(1) });
t.tasks_stop.write(|w| w.bits(1));
}
t.events_datardy.reset(); t.events_datardy.reset();
}); });
let t = Self::regs(); let t = Self::regs();
// Empty signal channel and start measurement. t.intenset.write(|w| w.datardy().set());
IRQ.reset();
unsafe { t.tasks_start.write(|w| w.bits(1)) }; unsafe { t.tasks_start.write(|w| w.bits(1)) };
async move { async move {
let value = IRQ.wait().await; let value = poll_fn(|cx| {
WAKER.register(cx.waker());
if t.events_datardy.read().bits() == 0 {
return Poll::Pending;
} else {
t.events_datardy.reset();
let raw = t.temp.read().bits();
Poll::Ready(I30F2::from_bits(raw as i32))
}
})
.await;
on_drop.defuse(); on_drop.defuse();
value value
} }