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
This commit is contained in:
parent
729b17bc25
commit
2ef4a45fa0
@ -48,6 +48,7 @@ embedded-dma = "0.1.2"
|
|||||||
futures = { version = "0.3.17", default-features = false }
|
futures = { version = "0.3.17", default-features = false }
|
||||||
critical-section = "0.2.3"
|
critical-section = "0.2.3"
|
||||||
rand_core = "0.6.3"
|
rand_core = "0.6.3"
|
||||||
|
fixed = "1.10.0"
|
||||||
|
|
||||||
nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||||
nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||||
|
@ -114,6 +114,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P0_29,
|
P0_29,
|
||||||
P0_30,
|
P0_30,
|
||||||
P0_31,
|
P0_31,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -117,6 +117,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P0_29,
|
P0_29,
|
||||||
P0_30,
|
P0_30,
|
||||||
P0_31,
|
P0_31,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -117,6 +117,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P0_29,
|
P0_29,
|
||||||
P0_30,
|
P0_30,
|
||||||
P0_31,
|
P0_31,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -112,6 +112,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P0_29,
|
P0_29,
|
||||||
P0_30,
|
P0_30,
|
||||||
P0_31,
|
P0_31,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -124,6 +124,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P0_29,
|
P0_29,
|
||||||
P0_30,
|
P0_30,
|
||||||
P0_31,
|
P0_31,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -144,6 +144,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P1_13,
|
P1_13,
|
||||||
P1_14,
|
P1_14,
|
||||||
P1_15,
|
P1_15,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -147,6 +147,9 @@ embassy_hal_common::peripherals! {
|
|||||||
P1_13,
|
P1_13,
|
||||||
P1_14,
|
P1_14,
|
||||||
P1_15,
|
P1_15,
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
TEMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -43,6 +43,8 @@ pub mod timer;
|
|||||||
pub mod twim;
|
pub mod twim;
|
||||||
pub mod uarte;
|
pub mod uarte;
|
||||||
pub mod wdt;
|
pub mod wdt;
|
||||||
|
#[cfg(not(feature = "nrf9160"))]
|
||||||
|
pub mod temp;
|
||||||
|
|
||||||
// This mod MUST go last, so that it sees all the `impl_foo!` macros
|
// This mod MUST go last, so that it sees all the `impl_foo!` macros
|
||||||
#[cfg(feature = "nrf52805")]
|
#[cfg(feature = "nrf52805")]
|
||||||
|
84
embassy-nrf/src/temp.rs
Normal file
84
embassy-nrf/src/temp.rs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//! Temperature sensor interface.
|
||||||
|
|
||||||
|
use crate::interrupt;
|
||||||
|
use crate::pac;
|
||||||
|
use crate::peripherals::TEMP;
|
||||||
|
|
||||||
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use embassy::channel::signal::Signal;
|
||||||
|
use embassy::interrupt::InterruptExt;
|
||||||
|
use embassy::util::Unborrow;
|
||||||
|
use embassy_hal_common::{drop::OnDrop, unborrow};
|
||||||
|
use fixed::types::I30F2;
|
||||||
|
|
||||||
|
/// Integrated temperature sensor.
|
||||||
|
pub struct Temp<'d> {
|
||||||
|
_temp: PhantomData<&'d TEMP>,
|
||||||
|
_irq: interrupt::TEMP,
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRQ: Signal<I30F2> = Signal::new();
|
||||||
|
|
||||||
|
impl<'d> Temp<'d> {
|
||||||
|
pub fn new(
|
||||||
|
_t: impl Unborrow<Target = TEMP> + 'd,
|
||||||
|
irq: impl Unborrow<Target = interrupt::TEMP> + 'd,
|
||||||
|
) -> Self {
|
||||||
|
unborrow!(_t, irq);
|
||||||
|
|
||||||
|
let t = Self::regs();
|
||||||
|
|
||||||
|
// Enable interrupt that signals temperature values
|
||||||
|
t.intenset.write(|w| w.datardy().set());
|
||||||
|
irq.disable();
|
||||||
|
irq.set_handler(|_| {
|
||||||
|
let t = Self::regs();
|
||||||
|
t.events_datardy.reset();
|
||||||
|
let raw = t.temp.read().bits();
|
||||||
|
IRQ.signal(I30F2::from_bits(raw as i32));
|
||||||
|
});
|
||||||
|
irq.enable();
|
||||||
|
Self {
|
||||||
|
_temp: PhantomData,
|
||||||
|
_irq: irq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perform an asynchronous temperature measurement. The returned future
|
||||||
|
/// can be awaited to obtain the measurement.
|
||||||
|
///
|
||||||
|
/// If the future is dropped, the measurement is cancelled.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// let mut t = Temp::new(p.TEMP, interrupt::take!(TEMP));
|
||||||
|
/// let v: u16 = t.read().await.to_num::<u16>();
|
||||||
|
/// ```
|
||||||
|
pub fn read(&mut self) -> impl Future<Output = I30F2> {
|
||||||
|
// In case the future is dropped, stop the task and reset events.
|
||||||
|
let on_drop = OnDrop::new(|| {
|
||||||
|
let t = Self::regs();
|
||||||
|
unsafe {
|
||||||
|
t.tasks_stop.write(|w| w.bits(1));
|
||||||
|
}
|
||||||
|
t.events_datardy.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
let t = Self::regs();
|
||||||
|
// Empty signal channel and start measurement.
|
||||||
|
IRQ.reset();
|
||||||
|
unsafe { t.tasks_start.write(|w| w.bits(1)) };
|
||||||
|
|
||||||
|
async move {
|
||||||
|
let value = IRQ.wait().await;
|
||||||
|
on_drop.defuse();
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn regs() -> &'static pac::temp::RegisterBlock {
|
||||||
|
unsafe { &*pac::TEMP::ptr() }
|
||||||
|
}
|
||||||
|
}
|
26
examples/nrf/src/bin/temp.rs
Normal file
26
examples/nrf/src/bin/temp.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
#[path = "../example_common.rs"]
|
||||||
|
mod example_common;
|
||||||
|
use example_common::*;
|
||||||
|
|
||||||
|
use defmt::panic;
|
||||||
|
use embassy::{
|
||||||
|
executor::Spawner,
|
||||||
|
time::{Duration, Timer},
|
||||||
|
};
|
||||||
|
use embassy_nrf::{interrupt, temp::Temp, Peripherals};
|
||||||
|
|
||||||
|
#[embassy::main]
|
||||||
|
async fn main(_spawner: Spawner, p: Peripherals) {
|
||||||
|
let irq = interrupt::take!(TEMP);
|
||||||
|
let mut temp = Temp::new(p.TEMP, irq);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let value = temp.read().await;
|
||||||
|
info!("temperature: {}", value.to_num::<u16>());
|
||||||
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user