Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Dion Dokter
2021-10-11 10:59:21 +02:00
25 changed files with 2161 additions and 167 deletions

View File

@ -159,6 +159,32 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -164,6 +164,48 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_02, ANALOGINPUT0);
impl_saadc_input!(P0_03, ANALOGINPUT1);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
impl_saadc_input!(P0_28, ANALOGINPUT4);
impl_saadc_input!(P0_29, ANALOGINPUT5);
impl_saadc_input!(P0_30, ANALOGINPUT6);
impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -165,6 +165,48 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_02, ANALOGINPUT0);
impl_saadc_input!(P0_03, ANALOGINPUT1);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
impl_saadc_input!(P0_28, ANALOGINPUT4);
impl_saadc_input!(P0_29, ANALOGINPUT5);
impl_saadc_input!(P0_30, ANALOGINPUT6);
impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -22,9 +22,6 @@ embassy_hal_common::peripherals! {
TWISPI0,
TWISPI1,
// SAADC
SAADC,
// TIMER
TIMER0,
TIMER1,
@ -163,6 +160,39 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -178,6 +178,48 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_02, ANALOGINPUT0);
impl_saadc_input!(P0_03, ANALOGINPUT1);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
impl_saadc_input!(P0_28, ANALOGINPUT4);
impl_saadc_input!(P0_29, ANALOGINPUT5);
impl_saadc_input!(P0_30, ANALOGINPUT6);
impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -218,6 +218,48 @@ impl_pin!(P1_13, 1, 13);
impl_pin!(P1_14, 1, 14);
impl_pin!(P1_15, 1, 15);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_02, ANALOGINPUT0);
impl_saadc_input!(P0_03, ANALOGINPUT1);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
impl_saadc_input!(P0_28, ANALOGINPUT4);
impl_saadc_input!(P0_29, ANALOGINPUT5);
impl_saadc_input!(P0_30, ANALOGINPUT6);
impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -223,6 +223,48 @@ impl_pin!(P1_13, 1, 13);
impl_pin!(P1_14, 1, 14);
impl_pin!(P1_15, 1, 15);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_ppi_channel!(PPI_CH16, 16, configurable);
impl_ppi_channel!(PPI_CH17, 17, configurable);
impl_ppi_channel!(PPI_CH18, 18, configurable);
impl_ppi_channel!(PPI_CH19, 19, configurable);
impl_ppi_channel!(PPI_CH20, 20);
impl_ppi_channel!(PPI_CH21, 21);
impl_ppi_channel!(PPI_CH22, 22);
impl_ppi_channel!(PPI_CH23, 23);
impl_ppi_channel!(PPI_CH24, 24);
impl_ppi_channel!(PPI_CH25, 25);
impl_ppi_channel!(PPI_CH26, 26);
impl_ppi_channel!(PPI_CH27, 27);
impl_ppi_channel!(PPI_CH28, 28);
impl_ppi_channel!(PPI_CH29, 29);
impl_ppi_channel!(PPI_CH30, 30);
impl_ppi_channel!(PPI_CH31, 31);
impl_saadc_input!(P0_02, ANALOGINPUT0);
impl_saadc_input!(P0_03, ANALOGINPUT1);
impl_saadc_input!(P0_04, ANALOGINPUT2);
impl_saadc_input!(P0_05, ANALOGINPUT3);
impl_saadc_input!(P0_28, ANALOGINPUT4);
impl_saadc_input!(P0_29, ANALOGINPUT5);
impl_saadc_input!(P0_30, ANALOGINPUT6);
impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -171,6 +171,32 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_ppi_channel!(PPI_CH0, 0, configurable);
impl_ppi_channel!(PPI_CH1, 1, configurable);
impl_ppi_channel!(PPI_CH2, 2, configurable);
impl_ppi_channel!(PPI_CH3, 3, configurable);
impl_ppi_channel!(PPI_CH4, 4, configurable);
impl_ppi_channel!(PPI_CH5, 5, configurable);
impl_ppi_channel!(PPI_CH6, 6, configurable);
impl_ppi_channel!(PPI_CH7, 7, configurable);
impl_ppi_channel!(PPI_CH8, 8, configurable);
impl_ppi_channel!(PPI_CH9, 9, configurable);
impl_ppi_channel!(PPI_CH10, 10, configurable);
impl_ppi_channel!(PPI_CH11, 11, configurable);
impl_ppi_channel!(PPI_CH12, 12, configurable);
impl_ppi_channel!(PPI_CH13, 13, configurable);
impl_ppi_channel!(PPI_CH14, 14, configurable);
impl_ppi_channel!(PPI_CH15, 15, configurable);
impl_saadc_input!(P0_13, ANALOGINPUT0);
impl_saadc_input!(P0_14, ANALOGINPUT1);
impl_saadc_input!(P0_15, ANALOGINPUT2);
impl_saadc_input!(P0_16, ANALOGINPUT3);
impl_saadc_input!(P0_17, ANALOGINPUT4);
impl_saadc_input!(P0_18, ANALOGINPUT5);
impl_saadc_input!(P0_19, ANALOGINPUT6);
impl_saadc_input!(P0_20, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;

View File

@ -266,14 +266,14 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
}
/// Triggers `task set` (set associated pin high).
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
pub fn set(&self) {
let g = unsafe { &*GPIOTE::ptr() };
g.tasks_set[self.ch.number()].write(|w| unsafe { w.bits(1) });
}
/// Triggers `task clear` (set associated pin low).
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
pub fn clear(&self) {
let g = unsafe { &*GPIOTE::ptr() };
g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) });
@ -286,14 +286,14 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
}
/// Returns the CLR task, for use with PPI.
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
pub fn task_clr(&self) -> Task {
let g = unsafe { &*GPIOTE::ptr() };
Task::from_reg(&g.tasks_clr[self.ch.number()])
}
/// Returns the SET task, for use with PPI.
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
pub fn task_set(&self) -> Task {
let g = unsafe { &*GPIOTE::ptr() };
Task::from_reg(&g.tasks_set[self.ch.number()])

View File

@ -1,3 +1,5 @@
#![macro_use]
//! HAL interface for the PPI peripheral.
//!
//! The Programmable Peripheral Interconnect interface allows for an autonomous interoperability
@ -38,7 +40,7 @@ impl<'d, C: Channel> Ppi<'d, C> {
ch,
phantom: PhantomData,
};
#[cfg(not(any(feature = "51", feature = "nrf9160")))]
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
this.clear_fork_task();
this
}
@ -57,7 +59,7 @@ impl<'d, C: Channel> Ppi<'d, C> {
.write(|w| unsafe { w.bits(1 << self.ch.number()) });
}
#[cfg(not(any(feature = "51", feature = "nrf9160")))]
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
/// Sets the fork task that must be triggered when the configured event occurs. The user must
/// provide a reference to the task.
pub fn set_fork_task(&mut self, task: Task) {
@ -67,7 +69,7 @@ impl<'d, C: Channel> Ppi<'d, C> {
.write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
}
#[cfg(not(any(feature = "51", feature = "nrf9160")))]
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
/// Clear the fork task endpoint. Previously set task will no longer be triggered.
pub fn clear_fork_task(&mut self) {
let r = unsafe { &*PPI::ptr() };
@ -143,7 +145,7 @@ impl Event {
}
}
mod sealed {
pub(crate) mod sealed {
pub trait ConfigurableChannel {}
pub trait Channel {}
pub trait Group {}
@ -201,15 +203,15 @@ impl Channel for AnyConfigurableChannel {
}
}
macro_rules! impl_channel {
macro_rules! impl_ppi_channel {
($type:ident, $number:expr, configurable) => {
impl_channel!($type, $number);
impl sealed::ConfigurableChannel for peripherals::$type {}
impl ConfigurableChannel for peripherals::$type {}
impl_ppi_channel!($type, $number);
impl crate::ppi::sealed::ConfigurableChannel for peripherals::$type {}
impl crate::ppi::ConfigurableChannel for peripherals::$type {}
};
($type:ident, $number:expr) => {
impl sealed::Channel for peripherals::$type {}
impl Channel for peripherals::$type {
impl crate::ppi::sealed::Channel for peripherals::$type {}
impl crate::ppi::Channel for peripherals::$type {
fn number(&self) -> usize {
$number
}
@ -217,70 +219,6 @@ macro_rules! impl_channel {
};
}
pub use channel_impl::*;
#[cfg(not(feature = "nrf9160"))]
mod channel_impl {
use super::*;
impl_channel!(PPI_CH0, 0, configurable);
impl_channel!(PPI_CH1, 1, configurable);
impl_channel!(PPI_CH2, 2, configurable);
impl_channel!(PPI_CH3, 3, configurable);
impl_channel!(PPI_CH4, 4, configurable);
impl_channel!(PPI_CH5, 5, configurable);
impl_channel!(PPI_CH6, 6, configurable);
impl_channel!(PPI_CH7, 7, configurable);
impl_channel!(PPI_CH8, 8, configurable);
impl_channel!(PPI_CH9, 9, configurable);
impl_channel!(PPI_CH10, 10, configurable);
impl_channel!(PPI_CH11, 11, configurable);
impl_channel!(PPI_CH12, 12, configurable);
impl_channel!(PPI_CH13, 13, configurable);
impl_channel!(PPI_CH14, 14, configurable);
impl_channel!(PPI_CH15, 15, configurable);
#[cfg(not(feature = "51",))]
impl_channel!(PPI_CH16, 16, configurable);
#[cfg(not(feature = "51"))]
impl_channel!(PPI_CH17, 17, configurable);
#[cfg(not(feature = "51"))]
impl_channel!(PPI_CH18, 18, configurable);
#[cfg(not(feature = "51"))]
impl_channel!(PPI_CH19, 19, configurable);
impl_channel!(PPI_CH20, 20);
impl_channel!(PPI_CH21, 21);
impl_channel!(PPI_CH22, 22);
impl_channel!(PPI_CH23, 23);
impl_channel!(PPI_CH24, 24);
impl_channel!(PPI_CH25, 25);
impl_channel!(PPI_CH26, 26);
impl_channel!(PPI_CH27, 27);
impl_channel!(PPI_CH28, 28);
impl_channel!(PPI_CH29, 29);
impl_channel!(PPI_CH30, 30);
impl_channel!(PPI_CH31, 31);
}
#[cfg(feature = "nrf9160")] // TODO: Implement configurability for nrf9160 and then remove these channel_impl modules
mod channel_impl {
use super::*;
impl_channel!(PPI_CH0, 0, configurable);
impl_channel!(PPI_CH1, 1, configurable);
impl_channel!(PPI_CH2, 2, configurable);
impl_channel!(PPI_CH3, 3, configurable);
impl_channel!(PPI_CH4, 4, configurable);
impl_channel!(PPI_CH5, 5, configurable);
impl_channel!(PPI_CH6, 6, configurable);
impl_channel!(PPI_CH7, 7, configurable);
impl_channel!(PPI_CH8, 8, configurable);
impl_channel!(PPI_CH9, 9, configurable);
impl_channel!(PPI_CH10, 10, configurable);
impl_channel!(PPI_CH11, 11, configurable);
impl_channel!(PPI_CH12, 12, configurable);
impl_channel!(PPI_CH13, 13, configurable);
impl_channel!(PPI_CH14, 14, configurable);
impl_channel!(PPI_CH15, 15, configurable);
}
// ======================
// groups
@ -310,7 +248,7 @@ impl_group!(PPI_GROUP0, 0);
impl_group!(PPI_GROUP1, 1);
impl_group!(PPI_GROUP2, 2);
impl_group!(PPI_GROUP3, 3);
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
impl_group!(PPI_GROUP4, 4);
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
impl_group!(PPI_GROUP5, 5);

View File

@ -1,3 +1,5 @@
#![macro_use]
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
@ -18,7 +20,7 @@ use pac::{saadc_ns as saadc, SAADC_NS as SAADC};
pub use saadc::{
ch::{
config::{GAIN_A as Gain, REFSEL_A as Reference, RESP_A as Resistor, TACQ_A as Time},
pselp::PSELP_A as PositiveChannel,
pselp::PSELP_A as InputChannel, // We treat the positive and negative channels with the same enum values to keep our type tidy and given they are the same
},
oversample::OVERSAMPLE_A as Oversample,
resolution::VAL_A as Resolution,
@ -30,7 +32,7 @@ pub use saadc::{
pub enum Error {}
/// One-shot saadc. Continuous sample mode TODO.
pub struct OneShot<'d> {
pub struct OneShot<'d, const N: usize> {
phantom: PhantomData<&'d mut peripherals::SAADC>,
}
@ -39,11 +41,29 @@ static WAKER: AtomicWaker = AtomicWaker::new();
/// Used to configure the SAADC peripheral.
///
/// See the `Default` impl for suitable default values.
#[non_exhaustive]
pub struct Config {
/// Output resolution in bits.
pub resolution: Resolution,
/// Average 2^`oversample` input samples before transferring the result into memory.
pub oversample: Oversample,
}
impl Default for Config {
/// Default configuration for single channel sampling.
fn default() -> Self {
Self {
resolution: Resolution::_14BIT,
oversample: Oversample::BYPASS,
}
}
}
/// Used to configure an individual SAADC peripheral channel.
///
/// See the `Default` impl for suitable default values.
#[non_exhaustive]
pub struct ChannelConfig<'d> {
/// Reference voltage of the SAADC input.
pub reference: Reference,
/// Gain used to control the effective input range of the SAADC.
@ -52,26 +72,52 @@ pub struct Config {
pub resistor: Resistor,
/// Acquisition time in microseconds.
pub time: Time,
/// Positive channel to sample
p_channel: InputChannel,
/// An optional negative channel to sample
n_channel: Option<InputChannel>,
phantom: PhantomData<&'d ()>,
}
impl Default for Config {
fn default() -> Self {
impl<'d> ChannelConfig<'d> {
/// Default configuration for single ended channel sampling.
pub fn single_ended(input: impl Unborrow<Target = impl Input> + 'd) -> Self {
unborrow!(input);
Self {
resolution: Resolution::_14BIT,
oversample: Oversample::OVER8X,
reference: Reference::VDD1_4,
gain: Gain::GAIN1_4,
reference: Reference::INTERNAL,
gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS,
time: Time::_20US,
time: Time::_10US,
p_channel: input.channel(),
n_channel: None,
phantom: PhantomData,
}
}
/// Default configuration for differential channel sampling.
pub fn differential(
p_input: impl Unborrow<Target = impl Input> + 'd,
n_input: impl Unborrow<Target = impl Input> + 'd,
) -> Self {
unborrow!(p_input, n_input);
Self {
reference: Reference::VDD1_4,
gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS,
time: Time::_10US,
p_channel: p_input.channel(),
n_channel: Some(n_input.channel()),
phantom: PhantomData,
}
}
}
impl<'d> OneShot<'d> {
impl<'d, const N: usize> OneShot<'d, N> {
pub fn new(
_saadc: impl Unborrow<Target = peripherals::SAADC> + 'd,
irq: impl Unborrow<Target = interrupt::SAADC> + 'd,
config: Config,
channel_configs: [ChannelConfig; N],
) -> Self {
unborrow!(irq);
@ -80,31 +126,39 @@ impl<'d> OneShot<'d> {
let Config {
resolution,
oversample,
reference,
gain,
resistor,
time,
} = config;
// Configure pins
// Configure channels
r.enable.write(|w| w.enable().enabled());
r.resolution.write(|w| w.val().variant(resolution));
r.oversample.write(|w| w.oversample().variant(oversample));
r.ch[0].config.write(|w| {
w.refsel().variant(reference);
w.gain().variant(gain);
w.tacq().variant(time);
w.mode().se();
w.resp().variant(resistor);
w.resn().bypass();
if !matches!(oversample, Oversample::BYPASS) {
w.burst().enabled();
} else {
w.burst().disabled();
for (i, cc) in channel_configs.iter().enumerate() {
r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel));
if let Some(n_channel) = cc.n_channel {
r.ch[i]
.pseln
.write(|w| unsafe { w.pseln().bits(n_channel as u8) });
}
w
});
r.ch[i].config.write(|w| {
w.refsel().variant(cc.reference);
w.gain().variant(cc.gain);
w.tacq().variant(cc.time);
if cc.n_channel.is_none() {
w.mode().se();
} else {
w.mode().diff();
}
w.resp().variant(cc.resistor);
w.resn().bypass();
if !matches!(oversample, Oversample::BYPASS) {
w.burst().enabled();
} else {
w.burst().disabled();
}
w
});
}
// Disable all events interrupts
r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) });
@ -131,18 +185,16 @@ impl<'d> OneShot<'d> {
unsafe { &*SAADC::ptr() }
}
pub async fn sample(&mut self, pin: &mut impl PositivePin) -> i16 {
pub async fn sample(&mut self, buf: &mut [i16; N]) {
let r = Self::regs();
// Set positive channel
r.ch[0].pselp.write(|w| w.pselp().variant(pin.channel()));
// Set up the DMA
let mut val: i16 = 0;
r.result
.ptr
.write(|w| unsafe { w.ptr().bits(((&mut val) as *mut _) as u32) });
r.result.maxcnt.write(|w| unsafe { w.maxcnt().bits(1) });
.write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as u32) });
r.result
.maxcnt
.write(|w| unsafe { w.maxcnt().bits(N as _) });
// Reset and enable the end event
r.events_end.reset();
@ -169,60 +221,27 @@ impl<'d> OneShot<'d> {
Poll::Pending
})
.await;
// The DMA wrote the sampled value to `val`.
val
}
}
impl<'d> Drop for OneShot<'d> {
impl<'d, const N: usize> Drop for OneShot<'d, N> {
fn drop(&mut self) {
let r = Self::regs();
r.enable.write(|w| w.enable().disabled());
}
}
/// A pin that can be used as the positive end of a ADC differential in the SAADC periperhal.
///
/// Currently negative is always shorted to ground (0V).
pub trait PositivePin {
fn channel(&self) -> PositiveChannel;
/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
pub trait Input {
fn channel(&self) -> InputChannel;
}
macro_rules! positive_pin_mappings {
( $($ch:ident => $pin:ident,)*) => {
$(
impl PositivePin for crate::peripherals::$pin {
fn channel(&self) -> PositiveChannel {
PositiveChannel::$ch
}
macro_rules! impl_saadc_input {
($pin:ident, $ch:ident) => {
impl crate::saadc::Input for crate::peripherals::$pin {
fn channel(&self) -> crate::saadc::InputChannel {
crate::saadc::InputChannel::$ch
}
)*
}
};
}
// TODO the variant names are unchecked
// the pins are copied from nrf hal
#[cfg(feature = "nrf9160")]
positive_pin_mappings! {
ANALOGINPUT0 => P0_13,
ANALOGINPUT1 => P0_14,
ANALOGINPUT2 => P0_15,
ANALOGINPUT3 => P0_16,
ANALOGINPUT4 => P0_17,
ANALOGINPUT5 => P0_18,
ANALOGINPUT6 => P0_19,
ANALOGINPUT7 => P0_20,
}
#[cfg(not(feature = "nrf9160"))]
positive_pin_mappings! {
ANALOGINPUT0 => P0_02,
ANALOGINPUT1 => P0_03,
ANALOGINPUT2 => P0_04,
ANALOGINPUT3 => P0_05,
ANALOGINPUT4 => P0_28,
ANALOGINPUT5 => P0_29,
ANALOGINPUT6 => P0_30,
ANALOGINPUT7 => P0_31,
}

View File

@ -8,7 +8,7 @@ pub(crate) fn slice_in_ram(slice: &[u8]) -> bool {
}
/// Return an error if slice is not in RAM.
#[cfg(not(feature = "51"))]
#[cfg(not(feature = "nrf51"))]
pub(crate) fn slice_in_ram_or<T>(slice: &[u8], err: T) -> Result<(), T> {
if slice.len() == 0 || slice_in_ram(slice) {
Ok(())