1use core::future::poll_fn;
4use core::task::Poll;
5
6use embassy_hal_internal::drop::OnDrop;
7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker;
9use fixed::types::I30F2;
10
11use crate::interrupt::InterruptExt;
12use crate::peripherals::TEMP;
13use crate::{interrupt, pac, Peripheral};
14
15pub struct InterruptHandler {
17 _private: (),
18}
19
20impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHandler {
21 unsafe fn on_interrupt() {
22 let r = pac::TEMP;
23 r.intenclr().write(|w| w.set_datardy(true));
24 WAKER.wake();
25 }
26}
27
28pub struct Temp<'d> {
30 _peri: PeripheralRef<'d, TEMP>,
31}
32
33static WAKER: AtomicWaker = AtomicWaker::new();
34
35impl<'d> Temp<'d> {
36 pub fn new(
38 _peri: impl Peripheral<P = TEMP> + 'd,
39 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd,
40 ) -> Self {
41 into_ref!(_peri);
42
43 interrupt::TEMP.unpend();
45 unsafe { interrupt::TEMP.enable() };
46
47 Self { _peri }
48 }
49
50 pub async fn read(&mut self) -> I30F2 {
72 let on_drop = OnDrop::new(|| {
74 let t = Self::regs();
75 t.tasks_stop().write_value(1);
76 t.events_datardy().write_value(0);
77 });
78
79 let t = Self::regs();
80 t.intenset().write(|w| w.set_datardy(true));
81 t.tasks_start().write_value(1);
82
83 let value = poll_fn(|cx| {
84 WAKER.register(cx.waker());
85 if t.events_datardy().read() == 0 {
86 Poll::Pending
87 } else {
88 t.events_datardy().write_value(0);
89 let raw = t.temp().read();
90 Poll::Ready(I30F2::from_bits(raw as i32))
91 }
92 })
93 .await;
94 on_drop.defuse();
95 value
96 }
97
98 fn regs() -> pac::temp::Temp {
99 pac::TEMP
100 }
101}