diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-10-19 18:50:37 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-10-19 18:50:37 +0000 |
| commit | 675172f9816a41792d53ba9dcd33ad3592e94eb8 (patch) | |
| tree | 1b22cf95d15a280917f7bb999dabd15d138f8075 | |
| parent | 729b17bc25fed42b4348cae0fb3d781590572c3f (diff) | |
| parent | 69953a78f10905330fb5d682dd5bda01f13a4e0c (diff) | |
Merge #436
436: Add support for temperature sensor peripheral r=lulf a=lulf
* Add TEMP peripheral to all nRF52 chips
* Add async HAL for reading temperature values
* Add example application reading temperature values
Co-authored-by: Ulf Lilleengen <[email protected]>
Co-authored-by: Ulf Lilleengen <[email protected]>
| -rw-r--r-- | embassy-nrf/Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52805.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52810.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52811.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52820.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52832.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52833.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf52840.rs | 3 | ||||
| -rw-r--r-- | embassy-nrf/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/temp.rs | 86 | ||||
| -rw-r--r-- | examples/nrf/src/bin/temp.rs | 26 |
11 files changed, 136 insertions, 0 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 7c5f8d32b..d4d4ab8d8 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -48,6 +48,7 @@ embedded-dma = "0.1.2" | |||
| 48 | futures = { version = "0.3.17", default-features = false } | 48 | futures = { version = "0.3.17", default-features = false } |
| 49 | critical-section = "0.2.3" | 49 | critical-section = "0.2.3" |
| 50 | rand_core = "0.6.3" | 50 | rand_core = "0.6.3" |
| 51 | fixed = "1.10.0" | ||
| 51 | 52 | ||
| 52 | nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } | 53 | nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } |
| 53 | nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } | 54 | nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } |
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index db1fac2ff..317e6ed66 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -114,6 +114,9 @@ embassy_hal_common::peripherals! { | |||
| 114 | P0_29, | 114 | P0_29, |
| 115 | P0_30, | 115 | P0_30, |
| 116 | P0_31, | 116 | P0_31, |
| 117 | |||
| 118 | // TEMP | ||
| 119 | TEMP, | ||
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 122 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 06b9bfb38..b26f30cbf 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -117,6 +117,9 @@ embassy_hal_common::peripherals! { | |||
| 117 | P0_29, | 117 | P0_29, |
| 118 | P0_30, | 118 | P0_30, |
| 119 | P0_31, | 119 | P0_31, |
| 120 | |||
| 121 | // TEMP | ||
| 122 | TEMP, | ||
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 125 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 2f8d98b31..9fbe3594e 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -117,6 +117,9 @@ embassy_hal_common::peripherals! { | |||
| 117 | P0_29, | 117 | P0_29, |
| 118 | P0_30, | 118 | P0_30, |
| 119 | P0_31, | 119 | P0_31, |
| 120 | |||
| 121 | // TEMP | ||
| 122 | TEMP, | ||
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 125 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index fc7a367ef..abbdba7ac 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -112,6 +112,9 @@ embassy_hal_common::peripherals! { | |||
| 112 | P0_29, | 112 | P0_29, |
| 113 | P0_30, | 113 | P0_30, |
| 114 | P0_31, | 114 | P0_31, |
| 115 | |||
| 116 | // TEMP | ||
| 117 | TEMP, | ||
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 120 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 47cf27de4..de6dd7a8c 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -124,6 +124,9 @@ embassy_hal_common::peripherals! { | |||
| 124 | P0_29, | 124 | P0_29, |
| 125 | P0_30, | 125 | P0_30, |
| 126 | P0_31, | 126 | P0_31, |
| 127 | |||
| 128 | // TEMP | ||
| 129 | TEMP, | ||
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 132 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index b3d813e24..c5e1c9d33 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -144,6 +144,9 @@ embassy_hal_common::peripherals! { | |||
| 144 | P1_13, | 144 | P1_13, |
| 145 | P1_14, | 145 | P1_14, |
| 146 | P1_15, | 146 | P1_15, |
| 147 | |||
| 148 | // TEMP | ||
| 149 | TEMP, | ||
| 147 | } | 150 | } |
| 148 | 151 | ||
| 149 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 152 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 473036f61..76cabe6f1 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -147,6 +147,9 @@ embassy_hal_common::peripherals! { | |||
| 147 | P1_13, | 147 | P1_13, |
| 148 | P1_14, | 148 | P1_14, |
| 149 | P1_15, | 149 | P1_15, |
| 150 | |||
| 151 | // TEMP | ||
| 152 | TEMP, | ||
| 150 | } | 153 | } |
| 151 | 154 | ||
| 152 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); | 155 | impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); |
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 00c719a17..961a97ce9 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -39,6 +39,8 @@ pub mod rng; | |||
| 39 | #[cfg(not(feature = "nrf52820"))] | 39 | #[cfg(not(feature = "nrf52820"))] |
| 40 | pub mod saadc; | 40 | pub mod saadc; |
| 41 | pub mod spim; | 41 | pub mod spim; |
| 42 | #[cfg(not(feature = "nrf9160"))] | ||
| 43 | pub mod temp; | ||
| 42 | pub mod timer; | 44 | pub mod timer; |
| 43 | pub mod twim; | 45 | pub mod twim; |
| 44 | pub mod uarte; | 46 | pub mod uarte; |
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs new file mode 100644 index 000000000..f7c6e6609 --- /dev/null +++ b/embassy-nrf/src/temp.rs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | //! Temperature sensor interface. | ||
| 2 | |||
| 3 | use crate::interrupt; | ||
| 4 | use crate::pac; | ||
| 5 | use crate::peripherals::TEMP; | ||
| 6 | |||
| 7 | use core::marker::PhantomData; | ||
| 8 | use core::task::Poll; | ||
| 9 | use embassy::interrupt::InterruptExt; | ||
| 10 | use embassy::util::Unborrow; | ||
| 11 | use embassy::waitqueue::AtomicWaker; | ||
| 12 | use embassy_hal_common::{drop::OnDrop, unborrow}; | ||
| 13 | use fixed::types::I30F2; | ||
| 14 | use futures::future::poll_fn; | ||
| 15 | |||
| 16 | /// Integrated temperature sensor. | ||
| 17 | pub struct Temp<'d> { | ||
| 18 | _temp: PhantomData<&'d TEMP>, | ||
| 19 | _irq: interrupt::TEMP, | ||
| 20 | } | ||
| 21 | |||
| 22 | static WAKER: AtomicWaker = AtomicWaker::new(); | ||
| 23 | |||
| 24 | impl<'d> Temp<'d> { | ||
| 25 | pub fn new( | ||
| 26 | _t: impl Unborrow<Target = TEMP> + 'd, | ||
| 27 | irq: impl Unborrow<Target = interrupt::TEMP> + 'd, | ||
| 28 | ) -> Self { | ||
| 29 | unborrow!(_t, irq); | ||
| 30 | |||
| 31 | // Enable interrupt that signals temperature values | ||
| 32 | irq.disable(); | ||
| 33 | irq.set_handler(|_| { | ||
| 34 | let t = Self::regs(); | ||
| 35 | t.intenclr.write(|w| w.datardy().clear()); | ||
| 36 | WAKER.wake(); | ||
| 37 | }); | ||
| 38 | irq.enable(); | ||
| 39 | Self { | ||
| 40 | _temp: PhantomData, | ||
| 41 | _irq: irq, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | /// Perform an asynchronous temperature measurement. The returned future | ||
| 46 | /// can be awaited to obtain the measurement. | ||
| 47 | /// | ||
| 48 | /// If the future is dropped, the measurement is cancelled. | ||
| 49 | /// | ||
| 50 | /// # Example | ||
| 51 | /// | ||
| 52 | /// ```no_run | ||
| 53 | /// let mut t = Temp::new(p.TEMP, interrupt::take!(TEMP)); | ||
| 54 | /// let v: u16 = t.read().await.to_num::<u16>(); | ||
| 55 | /// ``` | ||
| 56 | pub async fn read(&mut self) -> I30F2 { | ||
| 57 | // In case the future is dropped, stop the task and reset events. | ||
| 58 | let on_drop = OnDrop::new(|| { | ||
| 59 | let t = Self::regs(); | ||
| 60 | t.tasks_stop.write(|w| unsafe { w.bits(1) }); | ||
| 61 | t.events_datardy.reset(); | ||
| 62 | }); | ||
| 63 | |||
| 64 | let t = Self::regs(); | ||
| 65 | t.intenset.write(|w| w.datardy().set()); | ||
| 66 | unsafe { t.tasks_start.write(|w| w.bits(1)) }; | ||
| 67 | |||
| 68 | let value = poll_fn(|cx| { | ||
| 69 | WAKER.register(cx.waker()); | ||
| 70 | if t.events_datardy.read().bits() == 0 { | ||
| 71 | return Poll::Pending; | ||
| 72 | } else { | ||
| 73 | t.events_datardy.reset(); | ||
| 74 | let raw = t.temp.read().bits(); | ||
| 75 | Poll::Ready(I30F2::from_bits(raw as i32)) | ||
| 76 | } | ||
| 77 | }) | ||
| 78 | .await; | ||
| 79 | on_drop.defuse(); | ||
| 80 | value | ||
| 81 | } | ||
| 82 | |||
| 83 | fn regs() -> &'static pac::temp::RegisterBlock { | ||
| 84 | unsafe { &*pac::TEMP::ptr() } | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/examples/nrf/src/bin/temp.rs b/examples/nrf/src/bin/temp.rs new file mode 100644 index 000000000..af9775f5a --- /dev/null +++ b/examples/nrf/src/bin/temp.rs | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use example_common::*; | ||
| 8 | |||
| 9 | use defmt::panic; | ||
| 10 | use embassy::{ | ||
| 11 | executor::Spawner, | ||
| 12 | time::{Duration, Timer}, | ||
| 13 | }; | ||
| 14 | use embassy_nrf::{interrupt, temp::Temp, Peripherals}; | ||
| 15 | |||
| 16 | #[embassy::main] | ||
| 17 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 18 | let irq = interrupt::take!(TEMP); | ||
| 19 | let mut temp = Temp::new(p.TEMP, irq); | ||
| 20 | |||
| 21 | loop { | ||
| 22 | let value = temp.read().await; | ||
| 23 | info!("temperature: {}℃", value.to_num::<u16>()); | ||
| 24 | Timer::after(Duration::from_secs(1)).await; | ||
| 25 | } | ||
| 26 | } | ||
