aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/temp.rs
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2021-10-18 15:24:31 +0200
committerUlf Lilleengen <[email protected]>2021-10-19 07:18:56 +0200
commit2ef4a45fa0e153cb6435c4dc52f19108ca808cc7 (patch)
tree8681889a127109a49d592b2857232c18e64645a6 /embassy-nrf/src/temp.rs
parent729b17bc25fed42b4348cae0fb3d781590572c3f (diff)
Add support for temperature sensor peripheral
* Add TEMP peripheral to all nRF52 chips * Add async HAL for reading temperature values * Add example application reading temperature values
Diffstat (limited to 'embassy-nrf/src/temp.rs')
-rw-r--r--embassy-nrf/src/temp.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
new file mode 100644
index 000000000..6a334c64d
--- /dev/null
+++ b/embassy-nrf/src/temp.rs
@@ -0,0 +1,84 @@
1//! Temperature sensor interface.
2
3use crate::interrupt;
4use crate::pac;
5use crate::peripherals::TEMP;
6
7use core::future::Future;
8use core::marker::PhantomData;
9use embassy::channel::signal::Signal;
10use embassy::interrupt::InterruptExt;
11use embassy::util::Unborrow;
12use embassy_hal_common::{drop::OnDrop, unborrow};
13use fixed::types::I30F2;
14
15/// Integrated temperature sensor.
16pub struct Temp<'d> {
17 _temp: PhantomData<&'d TEMP>,
18 _irq: interrupt::TEMP,
19}
20
21static IRQ: Signal<I30F2> = Signal::new();
22
23impl<'d> Temp<'d> {
24 pub fn new(
25 _t: impl Unborrow<Target = TEMP> + 'd,
26 irq: impl Unborrow<Target = interrupt::TEMP> + 'd,
27 ) -> Self {
28 unborrow!(_t, irq);
29
30 let t = Self::regs();
31
32 // Enable interrupt that signals temperature values
33 t.intenset.write(|w| w.datardy().set());
34 irq.disable();
35 irq.set_handler(|_| {
36 let t = Self::regs();
37 t.events_datardy.reset();
38 let raw = t.temp.read().bits();
39 IRQ.signal(I30F2::from_bits(raw as i32));
40 });
41 irq.enable();
42 Self {
43 _temp: PhantomData,
44 _irq: irq,
45 }
46 }
47
48 /// Perform an asynchronous temperature measurement. The returned future
49 /// can be awaited to obtain the measurement.
50 ///
51 /// If the future is dropped, the measurement is cancelled.
52 ///
53 /// # Example
54 ///
55 /// ```no_run
56 /// let mut t = Temp::new(p.TEMP, interrupt::take!(TEMP));
57 /// let v: u16 = t.read().await.to_num::<u16>();
58 /// ```
59 pub fn read(&mut self) -> impl Future<Output = I30F2> {
60 // In case the future is dropped, stop the task and reset events.
61 let on_drop = OnDrop::new(|| {
62 let t = Self::regs();
63 unsafe {
64 t.tasks_stop.write(|w| w.bits(1));
65 }
66 t.events_datardy.reset();
67 });
68
69 let t = Self::regs();
70 // Empty signal channel and start measurement.
71 IRQ.reset();
72 unsafe { t.tasks_start.write(|w| w.bits(1)) };
73
74 async move {
75 let value = IRQ.wait().await;
76 on_drop.defuse();
77 value
78 }
79 }
80
81 fn regs() -> &'static pac::temp::RegisterBlock {
82 unsafe { &*pac::TEMP::ptr() }
83 }
84}