Use AtomicWaker instead of Signal
This commit is contained in:
parent
db3b315f94
commit
c777b6aae1
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user