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