From 20674f7126c52d5c9a7584f266463b3da8a1a38e Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 11 Oct 2021 10:39:38 +0200 Subject: [PATCH 1/6] Initial support for nrf9160 --- embassy-nrf/Cargo.toml | 2 + embassy-nrf/src/buffered_uarte.rs | 5 +- embassy-nrf/src/chips/nrf9160.rs | 209 ++++++++++++++++++++++++++++++ embassy-nrf/src/gpio.rs | 7 + embassy-nrf/src/gpiote.rs | 65 +++++++--- embassy-nrf/src/lib.rs | 20 ++- embassy-nrf/src/ppi.rs | 151 ++++++++++++++------- embassy-nrf/src/pwm.rs | 10 +- embassy-nrf/src/saadc.rs | 7 +- embassy-nrf/src/spim.rs | 11 +- embassy-nrf/src/time_driver.rs | 10 +- embassy-nrf/src/timer.rs | 11 +- embassy-nrf/src/twim.rs | 9 +- embassy-nrf/src/uarte.rs | 11 +- embassy-nrf/src/wdt.rs | 15 ++- rust-toolchain.toml | 2 +- 16 files changed, 458 insertions(+), 87 deletions(-) create mode 100644 embassy-nrf/src/chips/nrf9160.rs diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index d472069e7..7c5f8d32b 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -25,6 +25,7 @@ nrf52820 = ["nrf52820-pac"] nrf52832 = ["nrf52832-pac"] nrf52833 = ["nrf52833-pac"] nrf52840 = ["nrf52840-pac"] +nrf9160 = ["nrf9160-pac"] # Features starting with `_` are for internal use only. They're not intended # to be enabled by other crates, and are not covered by semver guarantees. @@ -55,3 +56,4 @@ nrf52820-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } +nrf9160-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index cd08875cd..31acb80d6 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -14,14 +14,13 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; -use crate::pac; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; -use crate::uarte::{Config, Instance as UarteInstance}; +use crate::uarte::{Config, Instance as UarteInstance, uarte0}; // Re-export SVD variants to allow user to directly set values -pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; +pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; #[derive(Copy, Clone, Debug, PartialEq)] enum RxState { diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs new file mode 100644 index 000000000..0730c1258 --- /dev/null +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -0,0 +1,209 @@ +pub use nrf9160_pac as pac; + +/// The maximum buffer size that the EasyDMA can send/recv in one operation. +pub const EASY_DMA_SIZE: usize = (1 << 12) - 1; +pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; + +embassy_hal_common::peripherals! { + // RTC + RTC0, + RTC1, + + // WDT + WDT, + + // UARTE + UARTE0, + UARTE1, + UARTE2, + UARTE3, + + // TWI + TWI0, + TWI1, + TWI2, + TWI3, + + // SPI + SPI0, + SPI1, + SPI2, + SPI3, + + // SAADC + SAADC, + + // PWM + PWM0, + PWM1, + PWM2, + PWM3, + + // TIMER + TIMER0, + TIMER1, + TIMER2, + + // GPIOTE + GPIOTE_CH0, + GPIOTE_CH1, + GPIOTE_CH2, + GPIOTE_CH3, + GPIOTE_CH4, + GPIOTE_CH5, + GPIOTE_CH6, + GPIOTE_CH7, + + // PPI + PPI_CH0, + PPI_CH1, + PPI_CH2, + PPI_CH3, + PPI_CH4, + PPI_CH5, + PPI_CH6, + PPI_CH7, + PPI_CH8, + PPI_CH9, + PPI_CH10, + PPI_CH11, + PPI_CH12, + PPI_CH13, + PPI_CH14, + PPI_CH15, + + PPI_GROUP0, + PPI_GROUP1, + PPI_GROUP2, + PPI_GROUP3, + PPI_GROUP4, + PPI_GROUP5, + + // GPIO port 0 + P0_00, + P0_01, + P0_02, + P0_03, + P0_04, + P0_05, + P0_06, + P0_07, + P0_08, + P0_09, + P0_10, + P0_11, + P0_12, + P0_13, + P0_14, + P0_15, + P0_16, + P0_17, + P0_18, + P0_19, + P0_20, + P0_21, + P0_22, + P0_23, + P0_24, + P0_25, + P0_26, + P0_27, + P0_28, + P0_29, + P0_30, + P0_31, +} + +impl_uarte!(UARTE0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_uarte!(UARTE1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_uarte!(UARTE2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_uarte!(UARTE3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); + +impl_spim!(SPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_spim!(SPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_spim!(SPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_spim!(SPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); + +impl_twim!(TWI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_twim!(TWI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_twim!(TWI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_twim!(TWI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); + +impl_pwm!(PWM0, PWM0_NS, PWM0); +impl_pwm!(PWM1, PWM1_NS, PWM1); +impl_pwm!(PWM2, PWM2_NS, PWM2); +impl_pwm!(PWM3, PWM3_NS, PWM3); + +impl_timer!(TIMER0, TIMER0_NS, TIMER0); +impl_timer!(TIMER1, TIMER1_NS, TIMER1); +impl_timer!(TIMER2, TIMER2_NS, TIMER2); + +impl_pin!(P0_00, 0, 0); +impl_pin!(P0_01, 0, 1); +impl_pin!(P0_02, 0, 2); +impl_pin!(P0_03, 0, 3); +impl_pin!(P0_04, 0, 4); +impl_pin!(P0_05, 0, 5); +impl_pin!(P0_06, 0, 6); +impl_pin!(P0_07, 0, 7); +impl_pin!(P0_08, 0, 8); +impl_pin!(P0_09, 0, 9); +impl_pin!(P0_10, 0, 10); +impl_pin!(P0_11, 0, 11); +impl_pin!(P0_12, 0, 12); +impl_pin!(P0_13, 0, 13); +impl_pin!(P0_14, 0, 14); +impl_pin!(P0_15, 0, 15); +impl_pin!(P0_16, 0, 16); +impl_pin!(P0_17, 0, 17); +impl_pin!(P0_18, 0, 18); +impl_pin!(P0_19, 0, 19); +impl_pin!(P0_20, 0, 20); +impl_pin!(P0_21, 0, 21); +impl_pin!(P0_22, 0, 22); +impl_pin!(P0_23, 0, 23); +impl_pin!(P0_24, 0, 24); +impl_pin!(P0_25, 0, 25); +impl_pin!(P0_26, 0, 26); +impl_pin!(P0_27, 0, 27); +impl_pin!(P0_28, 0, 28); +impl_pin!(P0_29, 0, 29); +impl_pin!(P0_30, 0, 30); +impl_pin!(P0_31, 0, 31); + +pub mod irqs { + use crate::pac::Interrupt as InterruptEnum; + use embassy_macros::interrupt_declare as declare; + + declare!(SPU); + declare!(CLOCK_POWER); + declare!(UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); + declare!(UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); + declare!(UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); + declare!(UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); + declare!(GPIOTE0); + declare!(SAADC); + declare!(TIMER0); + declare!(TIMER1); + declare!(TIMER2); + declare!(RTC0); + declare!(RTC1); + declare!(WDT); + declare!(EGU0); + declare!(EGU1); + declare!(EGU2); + declare!(EGU3); + declare!(EGU4); + declare!(EGU5); + declare!(PWM0); + declare!(PWM1); + declare!(PWM2); + declare!(PDM); + declare!(PWM3); + declare!(I2S); + declare!(IPC); + declare!(FPU); + declare!(GPIOTE1); + declare!(KMU); + declare!(CRYPTOCELL); +} diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index e30df7e7e..4cb1d36b9 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -10,7 +10,11 @@ use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; use gpio::pin_cnf::DRIVE_A; use crate::pac; + +#[cfg(not(feature = "nrf9160"))] use crate::pac::p0 as gpio; +#[cfg(feature = "nrf9160")] +use crate::pac::p0_ns as gpio; use self::sealed::Pin as _; @@ -299,7 +303,10 @@ pub(crate) mod sealed { fn block(&self) -> &gpio::RegisterBlock { unsafe { match self.pin_port() / 32 { + #[cfg(not(feature = "nrf9160"))] 0 => &*pac::P0::ptr(), + #[cfg(feature = "nrf9160")] + 0 => &*pac::P0_NS::ptr(), #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] 1 => &*pac::P1::ptr(), _ => unreachable_unchecked(), diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 001ee7fb8..fe181a3c6 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -22,6 +22,18 @@ pub const PIN_COUNT: usize = 48; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] pub const PIN_COUNT: usize = 32; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::P0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::P0_NS as P0; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::P1; + +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::GPIOTE; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::GPIOTE1_NS as GPIOTE; + const NEW_AW: AtomicWaker = AtomicWaker::new(); static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [NEW_AW; CHANNEL_COUNT]; static PORT_WAKERS: [AtomicWaker; PIN_COUNT] = [NEW_AW; PIN_COUNT]; @@ -42,9 +54,9 @@ pub enum OutputChannelPolarity { pub(crate) fn init(irq_prio: crate::interrupt::Priority) { #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] - let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; + let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] }; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] - let ports = unsafe { &[&*pac::P0::ptr()] }; + let ports = unsafe { &[&*P0::ptr()] }; for &p in ports { // Enable latched detection @@ -55,19 +67,34 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { // Enable interrupts + #[cfg(not(feature = "nrf9160"))] let irq = unsafe { interrupt::GPIOTE::steal() }; + #[cfg(feature = "nrf9160")] + let irq = unsafe { interrupt::GPIOTE1::steal() }; + irq.unpend(); irq.set_priority(irq_prio); irq.enable(); - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; g.events_port.write(|w| w); g.intenset.write(|w| w.port().set()); } +#[cfg(not(feature = "nrf9160"))] #[interrupt] -unsafe fn GPIOTE() { - let g = &*pac::GPIOTE::ptr(); +fn GPIOTE() { + unsafe { handle_gpiote_interrupt() }; +} + +#[cfg(feature = "nrf9160")] +#[interrupt] +fn GPIOTE1() { + unsafe { handle_gpiote_interrupt() }; +} + +unsafe fn handle_gpiote_interrupt() { + let g = &*GPIOTE::ptr(); for i in 0..CHANNEL_COUNT { if g.events_in[i].read().bits() != 0 { @@ -80,9 +107,9 @@ unsafe fn GPIOTE() { g.events_port.write(|w| w); #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] - let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()]; + let ports = &[&*P0::ptr(), &*P1::ptr()]; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] - let ports = &[&*pac::P0::ptr()]; + let ports = &[&*P0::ptr()]; for (port, &p) in ports.iter().enumerate() { let bits = p.latch.read().bits(); @@ -119,7 +146,7 @@ pub struct InputChannel<'d, C: Channel, T: GpioPin> { impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { fn drop(&mut self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -128,7 +155,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { pub fn new(ch: C, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; let num = ch.number(); g.config[num].write(|w| { @@ -152,7 +179,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { } pub async fn wait(&self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; let num = self.ch.number(); // Enable interrupt @@ -173,7 +200,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; Event::from_reg(&g.events_in[self.ch.number()]) } } @@ -198,7 +225,7 @@ pub struct OutputChannel<'d, C: Channel, T: GpioPin> { impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { fn drop(&mut self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -207,7 +234,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { pub fn new(ch: C, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; let num = ch.number(); g.config[num].write(|w| { @@ -234,41 +261,41 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). pub fn out(&self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; g.tasks_out[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task set` (set associated pin high). #[cfg(not(feature = "51"))] pub fn set(&self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + 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"))] pub fn clear(&self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; Task::from_reg(&g.tasks_out[self.ch.number()]) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "51"))] pub fn task_clr(&self) -> Task { - let g = unsafe { &*pac::GPIOTE::ptr() }; + 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"))] pub fn task_set(&self) -> Task { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = unsafe { &*GPIOTE::ptr() }; Task::from_reg(&g.tasks_set[self.ch.number()]) } } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 9a0e9c3a1..5924a42bb 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -34,6 +34,7 @@ pub mod ppi; pub mod pwm; #[cfg(feature = "nrf52840")] pub mod qspi; +#[cfg(not(feature = "nrf9160"))] pub mod rng; #[cfg(not(feature = "nrf52820"))] pub mod saadc; @@ -65,6 +66,9 @@ mod chip; #[cfg(feature = "nrf52840")] #[path = "chips/nrf52840.rs"] mod chip; +#[cfg(feature = "nrf9160")] +#[path = "chips/nrf9160.rs"] +mod chip; pub use chip::EASY_DMA_SIZE; @@ -75,6 +79,11 @@ pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals}; +#[cfg(feature = "nrf9160")] +use crate::pac::CLOCK_NS as CLOCK; +#[cfg(not(feature = "nrf9160"))] +use crate::pac::CLOCK; + pub mod interrupt { pub use crate::chip::irqs::*; pub use cortex_m::interrupt::{CriticalSection, Mutex}; @@ -91,9 +100,12 @@ pub mod config { pub enum LfclkSource { InternalRC, + #[cfg(not(feature = "nrf9160"))] Synthesized, ExternalXtal, + #[cfg(not(feature = "nrf9160"))] ExternalLowSwing, + #[cfg(not(feature = "nrf9160"))] ExternalFullSwing, } @@ -129,7 +141,7 @@ pub fn init(config: config::Config) -> Peripherals { // before doing anything important. let peripherals = Peripherals::take(); - let r = unsafe { &*pac::CLOCK::ptr() }; + let r = unsafe { &*CLOCK::ptr() }; // Start HFCLK. match config.hfclk_source { @@ -143,6 +155,7 @@ pub fn init(config: config::Config) -> Peripherals { } // Configure LFCLK. + #[cfg(not(feature = "nrf9160"))] match config.lfclk_source { config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), @@ -162,6 +175,11 @@ pub fn init(config: config::Config) -> Peripherals { w }), } + #[cfg(feature = "nrf9160")] + match config.lfclk_source { + config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().lfrc()), + config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().lfxo()), + } // Start LFCLK. // Datasheet says this could take 100us from synth source diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index 61028c03a..1d1f88915 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -16,6 +16,11 @@ use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; use crate::{pac, peripherals}; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::PPI; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::DPPIC_NS as PPI; + // ====================== // driver @@ -27,45 +32,60 @@ pub struct Ppi<'d, C: Channel> { impl<'d, C: Channel> Ppi<'d, C> { pub fn new(ch: impl Unborrow + 'd) -> Self { unborrow!(ch); + + #[allow(unused_mut)] let mut this = Self { ch, phantom: PhantomData, }; - #[cfg(not(feature = "51"))] + #[cfg(not(any(feature = "51", feature = "nrf9160")))] this.clear_fork_task(); this } /// Enables the channel. pub fn enable(&mut self) { - let r = unsafe { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.chenset .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } /// Disables the channel. pub fn disable(&mut self) { - let r = unsafe { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.chenclr .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } - #[cfg(not(feature = "51"))] + #[cfg(not(any(feature = "51", 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) { - let r = unsafe { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.fork[self.ch.number()] .tep .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) } - #[cfg(not(feature = "51"))] + #[cfg(not(any(feature = "51", 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 { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) } + + #[cfg(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) { + todo!("Tasks not yet implemented for nrf9160"); + } + + #[cfg(feature = "nrf9160")] + /// Clear the fork task endpoint. Previously set task will no longer be triggered. + pub fn clear_fork_task(&mut self) { + todo!("Tasks not yet implemented for nrf9160"); + } } impl<'d, C: Channel> Drop for Ppi<'d, C> { @@ -74,10 +94,11 @@ impl<'d, C: Channel> Drop for Ppi<'d, C> { } } +#[cfg(not(feature = "nrf9160"))] impl<'d, C: ConfigurableChannel> Ppi<'d, C> { /// Sets the task to be triggered when the configured event occurs. pub fn set_task(&mut self, task: Task) { - let r = unsafe { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.ch[self.ch.number()] .tep .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) @@ -85,13 +106,26 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C> { /// Sets the event that will trigger the chosen task(s). pub fn set_event(&mut self, event: Event) { - let r = unsafe { &*pac::PPI::ptr() }; + let r = unsafe { &*PPI::ptr() }; r.ch[self.ch.number()] .eep .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) } } +#[cfg(feature = "nrf9160")] +impl<'d, C: ConfigurableChannel> Ppi<'d, C> { + /// Sets the task to be triggered when the configured event occurs. + pub fn set_task(&mut self, _task: Task) { + todo!("Tasks not yet implemented for nrf9160") + } + + /// Sets the event that will trigger the chosen task(s). + pub fn set_event(&mut self, _event: Event) { + todo!("Events not yet implemented for nrf9160") + } +} + // ====================== // traits @@ -183,42 +217,69 @@ macro_rules! impl_channel { }; } -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); +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 diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 5e996e882..057a13594 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -11,6 +11,12 @@ use crate::gpio::OptionalPin as GpioOptionalPin; use crate::interrupt::Interrupt; use crate::pac; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::pwm0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::pwm0_ns as pwm0; + + #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub enum Prescaler { Div1, @@ -203,7 +209,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static pac::pwm0::RegisterBlock; + fn regs() -> &'static pwm0::RegisterBlock; fn state() -> &'static State; } } @@ -215,7 +221,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_pwm { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::pwm::sealed::Instance for peripherals::$type { - fn regs() -> &'static pac::pwm0::RegisterBlock { + fn regs() -> &'static crate::pwm::pwm0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::pwm::sealed::State { diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index b6e8f4e44..49a71e497 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -10,7 +10,10 @@ use futures::future::poll_fn; use crate::interrupt; use crate::{pac, peripherals}; +#[cfg(not(feature = "nrf9160"))] use pac::{saadc, SAADC}; +#[cfg(feature = "nrf9160")] +use pac::{saadc_ns as saadc, SAADC_NS as SAADC}; pub use saadc::{ ch::{ @@ -200,7 +203,7 @@ macro_rules! positive_pin_mappings { // TODO the variant names are unchecked // the pins are copied from nrf hal -#[cfg(feature = "9160")] +#[cfg(feature = "nrf9160")] positive_pin_mappings! { ANALOGINPUT0 => P0_13, ANALOGINPUT1 => P0_14, @@ -212,7 +215,7 @@ positive_pin_mappings! { ANALOGINPUT7 => P0_20, } -#[cfg(not(feature = "9160"))] +#[cfg(not(feature = "nrf9160"))] positive_pin_mappings! { ANALOGINPUT0 => P0_02, ANALOGINPUT1 => P0_03, diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index e88fb460c..f40da54e5 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -17,8 +17,13 @@ use crate::gpio::{OptionalPin, Pin as GpioPin}; use crate::interrupt::Interrupt; use crate::{pac, util::slice_in_ram_or}; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::spim0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::spim0_ns as spim0; + pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -pub use pac::spim0::frequency::FREQUENCY_A as Frequency; +pub use spim0::frequency::FREQUENCY_A as Frequency; #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -376,7 +381,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static pac::spim0::RegisterBlock; + fn regs() -> &'static spim0::RegisterBlock; fn state() -> &'static State; } } @@ -388,7 +393,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_spim { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::spim::sealed::Instance for peripherals::$type { - fn regs() -> &'static pac::spim0::RegisterBlock { + fn regs() -> &'static crate::spim::spim0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::spim::sealed::State { diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 19356c2d2..366f270c0 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs @@ -9,8 +9,16 @@ use embassy::time::driver::{AlarmHandle, Driver}; use crate::interrupt; use crate::pac; -fn rtc() -> &'static pac::rtc0::RegisterBlock { +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::rtc0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::rtc0_ns as rtc0; + +fn rtc() -> &'static rtc0::RegisterBlock { + #[cfg(not(feature = "nrf9160"))] unsafe { &*pac::RTC1::ptr() } + #[cfg(feature = "nrf9160")] + unsafe { &*pac::RTC1_NS::ptr() } } // RTC timekeeping works with something we call "periods", which are time intervals diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 5690ff0d8..066609ec6 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -15,6 +15,11 @@ use crate::pac; use crate::ppi::Event; use crate::ppi::Task; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::timer0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::timer0_ns as timer0; + pub(crate) mod sealed { use super::*; @@ -22,7 +27,7 @@ pub(crate) mod sealed { pub trait Instance { /// The number of CC registers this instance has. const CCS: usize; - fn regs() -> &'static pac::timer0::RegisterBlock; + fn regs() -> &'static timer0::RegisterBlock; /// Storage for the waker for CC register `n`. fn waker(n: usize) -> &'static AtomicWaker; } @@ -40,8 +45,8 @@ macro_rules! impl_timer { ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => { impl crate::timer::sealed::Instance for peripherals::$type { const CCS: usize = $ccs; - fn regs() -> &'static pac::timer0::RegisterBlock { - unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } + fn regs() -> &'static crate::timer::timer0::RegisterBlock { + unsafe { &*(pac::$pac_type::ptr() as *const crate::timer::timer0::RegisterBlock) } } fn waker(n: usize) -> &'static ::embassy::waitqueue::AtomicWaker { use ::embassy::waitqueue::AtomicWaker; diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 8173f66b0..8dcfb4143 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -24,6 +24,11 @@ use crate::gpio::Pin as GpioPin; use crate::pac; use crate::util::{slice_in_ram, slice_in_ram_or}; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::twim0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::twim0_ns as twim0; + pub enum Frequency { #[doc = "26738688: 100 kbps"] K100 = 26738688, @@ -721,7 +726,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static pac::twim0::RegisterBlock; + fn regs() -> &'static twim0::RegisterBlock; fn state() -> &'static State; } } @@ -733,7 +738,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_twim { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::twim::sealed::Instance for peripherals::$type { - fn regs() -> &'static pac::twim0::RegisterBlock { + fn regs() -> &'static crate::twim::twim0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::twim::sealed::State { diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 320426060..286e324b0 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -22,8 +22,13 @@ use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::uarte0; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::uarte0_ns as uarte0; + // Re-export SVD variants to allow user to directly set values. -pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; +pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; #[non_exhaustive] pub struct Config { @@ -458,7 +463,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static pac::uarte0::RegisterBlock; + fn regs() -> &'static uarte0::RegisterBlock; fn state() -> &'static State; } } @@ -470,7 +475,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static + Send macro_rules! impl_uarte { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::uarte::sealed::Instance for peripherals::$type { - fn regs() -> &'static pac::uarte0::RegisterBlock { + fn regs() -> &'static crate::uarte::uarte0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::uarte::sealed::State { diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index cd62d0d60..98ddd71af 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs @@ -3,7 +3,13 @@ //! This HAL implements a basic watchdog timer with 1..=8 handles. //! Once the watchdog has been started, it cannot be stopped. -use crate::pac::WDT; +use crate::pac; + +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::WDT; +#[cfg(feature = "nrf9160")] +pub(crate) use pac::WDT_NS as WDT; + use crate::peripherals; const MIN_TICKS: u32 = 15; @@ -58,7 +64,12 @@ impl Watchdog { let crv = config.timeout_ticks.max(MIN_TICKS); let rren = (1u32 << N) - 1; - if r.runstatus.read().runstatus().bit() { + #[cfg(not(feature = "nrf9160"))] + let runstatus = r.runstatus.read().runstatus().bit(); + #[cfg(feature = "nrf9160")] + let runstatus = r.runstatus.read().runstatuswdt().bit(); + + if runstatus { let curr_config = r.config.read(); if curr_config.halt().bit() != config.run_during_debug_halt || curr_config.sleep().bit() != config.run_during_sleep diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8f3473433..00901f820 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -3,4 +3,4 @@ [toolchain] channel = "nightly-2021-08-18" components = [ "rust-src", "rustfmt" ] -targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ] +targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ] From 4643727fea491e91f5afe9532775d0e422f744f6 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 11 Oct 2021 15:12:40 +0200 Subject: [PATCH 2/6] Made all PPI channels not configurable (even though they are) so they can't use unimplemented features --- embassy-nrf/src/chips/nrf9160.rs | 32 ++++++++++++++++---------------- embassy-nrf/src/twim.rs | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 75b9e71d2..1086c73c1 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -171,22 +171,22 @@ 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_CH0, 0); +impl_ppi_channel!(PPI_CH1, 1); +impl_ppi_channel!(PPI_CH2, 2); +impl_ppi_channel!(PPI_CH3, 3); +impl_ppi_channel!(PPI_CH4, 4); +impl_ppi_channel!(PPI_CH5, 5); +impl_ppi_channel!(PPI_CH6, 6); +impl_ppi_channel!(PPI_CH7, 7); +impl_ppi_channel!(PPI_CH8, 8); +impl_ppi_channel!(PPI_CH9, 9); +impl_ppi_channel!(PPI_CH10, 10); +impl_ppi_channel!(PPI_CH11, 11); +impl_ppi_channel!(PPI_CH12, 12); +impl_ppi_channel!(PPI_CH13, 13); +impl_ppi_channel!(PPI_CH14, 14); +impl_ppi_channel!(PPI_CH15, 15); impl_saadc_input!(P0_13, ANALOGINPUT0); impl_saadc_input!(P0_14, ANALOGINPUT1); diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 8dcfb4143..2d51480d8 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -184,7 +184,7 @@ impl<'d, T: Instance> Twim<'d, T> { // The PTR field is a full 32 bits wide and accepts the full range // of values. w.ptr().bits(buffer.as_mut_ptr() as u32)); - r.rxd.maxcnt.write(|w| + r.rxd.maxcnt.write(|w| // We're giving it the length of the buffer, so no danger of // accessing invalid memory. We have verified that the length of the // buffer fits in an `u8`, so the cast to the type of maxcnt From 995cd01cbcb2470b9ecdd953daae0cfb3aaa2e99 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 11 Oct 2021 15:31:25 +0200 Subject: [PATCH 3/6] ran fmt --- embassy-nrf/src/buffered_uarte.rs | 2 +- embassy-nrf/src/lib.rs | 4 ++-- embassy-nrf/src/ppi.rs | 4 ++-- embassy-nrf/src/pwm.rs | 1 - embassy-nrf/src/time_driver.rs | 8 ++++++-- embassy-nrf/src/twim.rs | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 31acb80d6..e999cb721 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -17,7 +17,7 @@ use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; -use crate::uarte::{Config, Instance as UarteInstance, uarte0}; +use crate::uarte::{uarte0, Config, Instance as UarteInstance}; // Re-export SVD variants to allow user to directly set values pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 5924a42bb..2ee04708d 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -79,10 +79,10 @@ pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals}; -#[cfg(feature = "nrf9160")] -use crate::pac::CLOCK_NS as CLOCK; #[cfg(not(feature = "nrf9160"))] use crate::pac::CLOCK; +#[cfg(feature = "nrf9160")] +use crate::pac::CLOCK_NS as CLOCK; pub mod interrupt { pub use crate::chip::irqs::*; diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index 727f6913c..db5387b8e 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -18,10 +18,10 @@ use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; use crate::{pac, peripherals}; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::PPI; #[cfg(feature = "nrf9160")] pub(crate) use pac::DPPIC_NS as PPI; +#[cfg(not(feature = "nrf9160"))] +pub(crate) use pac::PPI; // ====================== // driver diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 057a13594..1bafb1d48 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -16,7 +16,6 @@ pub(crate) use pac::pwm0; #[cfg(feature = "nrf9160")] pub(crate) use pac::pwm0_ns as pwm0; - #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub enum Prescaler { Div1, diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 366f270c0..4c2438a00 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs @@ -16,9 +16,13 @@ pub(crate) use pac::rtc0_ns as rtc0; fn rtc() -> &'static rtc0::RegisterBlock { #[cfg(not(feature = "nrf9160"))] - unsafe { &*pac::RTC1::ptr() } + unsafe { + &*pac::RTC1::ptr() + } #[cfg(feature = "nrf9160")] - unsafe { &*pac::RTC1_NS::ptr() } + unsafe { + &*pac::RTC1_NS::ptr() + } } // RTC timekeeping works with something we call "periods", which are time intervals diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 2d51480d8..8dcfb4143 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -184,7 +184,7 @@ impl<'d, T: Instance> Twim<'d, T> { // The PTR field is a full 32 bits wide and accepts the full range // of values. w.ptr().bits(buffer.as_mut_ptr() as u32)); - r.rxd.maxcnt.write(|w| + r.rxd.maxcnt.write(|w| // We're giving it the length of the buffer, so no danger of // accessing invalid memory. We have verified that the length of the // buffer fits in an `u8`, so the cast to the type of maxcnt From 2c2c284482ee57595ad4eef542f4867f6f87bf12 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 12 Oct 2021 11:43:57 +0200 Subject: [PATCH 4/6] Undoing unnecessary changes --- embassy-nrf/src/buffered_uarte.rs | 5 ++- embassy-nrf/src/chips/nrf9160.rs | 75 ++++++++++++++++++------------- embassy-nrf/src/gpio.rs | 9 +--- embassy-nrf/src/gpiote.rs | 48 ++++++++------------ embassy-nrf/src/lib.rs | 6 +-- embassy-nrf/src/ppi.rs | 20 +++------ embassy-nrf/src/pwm.rs | 9 +--- embassy-nrf/src/saadc.rs | 3 -- embassy-nrf/src/spim.rs | 11 ++--- embassy-nrf/src/time_driver.rs | 16 +------ embassy-nrf/src/timer.rs | 11 ++--- embassy-nrf/src/twim.rs | 9 +--- embassy-nrf/src/uarte.rs | 11 ++--- embassy-nrf/src/wdt.rs | 8 +--- 14 files changed, 90 insertions(+), 151 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index e999cb721..cd08875cd 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -14,13 +14,14 @@ use embassy_hal_common::{low_power_wait_until, unborrow}; use crate::gpio::sealed::Pin as _; use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; +use crate::pac; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; -use crate::uarte::{uarte0, Config, Instance as UarteInstance}; +use crate::uarte::{Config, Instance as UarteInstance}; // Re-export SVD variants to allow user to directly set values -pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; +pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; #[derive(Copy, Clone, Debug, PartialEq)] enum RxState { diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 1086c73c1..42053d081 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -1,7 +1,32 @@ -pub use nrf9160_pac as pac; +#[allow(unused_imports)] +pub mod pac { + // The nRF9160 has a secure and non-secure (NS) mode. + // For now we only support the NS mode, but those peripherals have `_ns` appended to them. + // To avoid cfg spam, weŕe going to rename the ones we use here. + #[rustfmt::skip] + pub(crate) use nrf9160_pac::{ + p0_ns as p0, + pwm0_ns as pwm0, + rtc0_ns as rtc0, + spim0_ns as spim0, + timer0_ns as timer0, + twim0_ns as twim0, + uarte0_ns as uarte0, + DPPIC_NS as PPI, + GPIOTE1_NS as GPIOTE, + P0_NS as P0, + RTC1_NS as RTC1, + WDT_NS as WDT, + saadc_ns as saadc, + SAADC_NS as SAADC, + CLOCK_NS as CLOCK, + }; + + pub use nrf9160_pac::*; +} /// The maximum buffer size that the EasyDMA can send/recv in one operation. -pub const EASY_DMA_SIZE: usize = (1 << 12) - 1; +pub const EASY_DMA_SIZE: usize = (1 << 13) - 1; pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; embassy_hal_common::peripherals! { @@ -12,23 +37,11 @@ embassy_hal_common::peripherals! { // WDT WDT, - // UARTE - UARTE0, - UARTE1, - UARTE2, - UARTE3, - - // TWI - TWI0, - TWI1, - TWI2, - TWI3, - - // SPI - SPI0, - SPI1, - SPI2, - SPI3, + // UARTE, TWI & SPI + UARTETWISPI0, + UARTETWISPI1, + UARTETWISPI2, + UARTETWISPI3, // SAADC SAADC, @@ -114,20 +127,20 @@ embassy_hal_common::peripherals! { P0_31, } -impl_uarte!(UARTE0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); -impl_uarte!(UARTE1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); -impl_uarte!(UARTE2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); -impl_uarte!(UARTE3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); +impl_uarte!(UARTETWISPI0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_uarte!(UARTETWISPI1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_uarte!(UARTETWISPI2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_uarte!(UARTETWISPI3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); -impl_spim!(SPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); -impl_spim!(SPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); -impl_spim!(SPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); -impl_spim!(SPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); +impl_spim!(UARTETWISPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_spim!(UARTETWISPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_spim!(UARTETWISPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_spim!(UARTETWISPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); -impl_twim!(TWI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); -impl_twim!(TWI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); -impl_twim!(TWI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); -impl_twim!(TWI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); +impl_twim!(UARTETWISPI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); +impl_twim!(UARTETWISPI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); +impl_twim!(UARTETWISPI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); +impl_twim!(UARTETWISPI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); impl_pwm!(PWM0, PWM0_NS, PWM0); impl_pwm!(PWM1, PWM1_NS, PWM1); diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 4cb1d36b9..be0fac2b0 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -10,18 +10,14 @@ use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; use gpio::pin_cnf::DRIVE_A; use crate::pac; - -#[cfg(not(feature = "nrf9160"))] use crate::pac::p0 as gpio; -#[cfg(feature = "nrf9160")] -use crate::pac::p0_ns as gpio; use self::sealed::Pin as _; /// A GPIO port with up to 32 pins. #[derive(Debug, Eq, PartialEq)] pub enum Port { - /// Port 0, available on all nRF52 and nRF51 MCUs. + /// Port 0, available on nRF9160 and all nRF52 and nRF51 MCUs. Port0, /// Port 1, only available on some nRF52 MCUs. @@ -303,10 +299,7 @@ pub(crate) mod sealed { fn block(&self) -> &gpio::RegisterBlock { unsafe { match self.pin_port() / 32 { - #[cfg(not(feature = "nrf9160"))] 0 => &*pac::P0::ptr(), - #[cfg(feature = "nrf9160")] - 0 => &*pac::P0_NS::ptr(), #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] 1 => &*pac::P1::ptr(), _ => unreachable_unchecked(), diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 6cf9c9a39..bab49cebb 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -22,18 +22,6 @@ pub const PIN_COUNT: usize = 48; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] pub const PIN_COUNT: usize = 32; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::P0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::P0_NS as P0; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::P1; - -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::GPIOTE; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::GPIOTE1_NS as GPIOTE; - const NEW_AW: AtomicWaker = AtomicWaker::new(); static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [NEW_AW; CHANNEL_COUNT]; static PORT_WAKERS: [AtomicWaker; PIN_COUNT] = [NEW_AW; PIN_COUNT]; @@ -54,9 +42,9 @@ pub enum OutputChannelPolarity { pub(crate) fn init(irq_prio: crate::interrupt::Priority) { #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] - let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] }; + let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] - let ports = unsafe { &[&*P0::ptr()] }; + let ports = unsafe { &[&*pac::P0::ptr()] }; for &p in ports { // Enable latched detection @@ -76,7 +64,7 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { irq.set_priority(irq_prio); irq.enable(); - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; g.events_port.write(|w| w); g.intenset.write(|w| w.port().set()); } @@ -94,7 +82,7 @@ fn GPIOTE1() { } unsafe fn handle_gpiote_interrupt() { - let g = &*GPIOTE::ptr(); + let g = &*pac::GPIOTE::ptr(); for i in 0..CHANNEL_COUNT { if g.events_in[i].read().bits() != 0 { @@ -107,9 +95,9 @@ unsafe fn handle_gpiote_interrupt() { g.events_port.write(|w| w); #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] - let ports = &[&*P0::ptr(), &*P1::ptr()]; + let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()]; #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] - let ports = &[&*P0::ptr()]; + let ports = &[&*pac::P0::ptr()]; for (port, &p) in ports.iter().enumerate() { let bits = p.latch.read().bits(); @@ -146,7 +134,7 @@ pub struct InputChannel<'d, C: Channel, T: GpioPin> { impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { fn drop(&mut self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -155,7 +143,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> { impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { pub fn new(ch: C, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; let num = ch.number(); g.config[num].write(|w| { @@ -179,7 +167,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { } pub async fn wait(&self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; let num = self.ch.number(); // Enable interrupt @@ -200,7 +188,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { /// Returns the IN event, for use with PPI. pub fn event_in(&self) -> Event { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; Event::from_reg(&g.events_in[self.ch.number()]) } } @@ -225,7 +213,7 @@ pub struct OutputChannel<'d, C: Channel, T: GpioPin> { impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { fn drop(&mut self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -234,7 +222,7 @@ impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> { impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { pub fn new(ch: C, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; let num = ch.number(); g.config[num].write(|w| { @@ -261,41 +249,41 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). pub fn out(&self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; g.tasks_out[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task set` (set associated pin high). #[cfg(not(feature = "nrf51"))] pub fn set(&self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; g.tasks_set[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Triggers `task clear` (set associated pin low). #[cfg(not(feature = "nrf51"))] pub fn clear(&self) { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) }); } /// Returns the OUT task, for use with PPI. pub fn task_out(&self) -> Task { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; Task::from_reg(&g.tasks_out[self.ch.number()]) } /// Returns the CLR task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_clr(&self) -> Task { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; Task::from_reg(&g.tasks_clr[self.ch.number()]) } /// Returns the SET task, for use with PPI. #[cfg(not(feature = "nrf51"))] pub fn task_set(&self) -> Task { - let g = unsafe { &*GPIOTE::ptr() }; + let g = unsafe { &*pac::GPIOTE::ptr() }; Task::from_reg(&g.tasks_set[self.ch.number()]) } } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 2ee04708d..00c719a17 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -77,12 +77,8 @@ pub use chip::pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use chip::pac; -pub use chip::{peripherals, Peripherals}; - -#[cfg(not(feature = "nrf9160"))] use crate::pac::CLOCK; -#[cfg(feature = "nrf9160")] -use crate::pac::CLOCK_NS as CLOCK; +pub use chip::{peripherals, Peripherals}; pub mod interrupt { pub use crate::chip::irqs::*; diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs index db5387b8e..f5e06c69f 100644 --- a/embassy-nrf/src/ppi.rs +++ b/embassy-nrf/src/ppi.rs @@ -11,18 +11,12 @@ //! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task //! to be triggered by the same event, even fixed PPI channels have a configurable fork task. +use crate::{pac, peripherals}; use core::marker::PhantomData; use core::ptr::NonNull; use embassy::util::Unborrow; use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; -use crate::{pac, peripherals}; - -#[cfg(feature = "nrf9160")] -pub(crate) use pac::DPPIC_NS as PPI; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::PPI; - // ====================== // driver @@ -47,14 +41,14 @@ impl<'d, C: Channel> Ppi<'d, C> { /// Enables the channel. pub fn enable(&mut self) { - let r = unsafe { &*PPI::ptr() }; + let r = unsafe { &*pac::PPI::ptr() }; r.chenset .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } /// Disables the channel. pub fn disable(&mut self) { - let r = unsafe { &*PPI::ptr() }; + let r = unsafe { &*pac::PPI::ptr() }; r.chenclr .write(|w| unsafe { w.bits(1 << self.ch.number()) }); } @@ -63,7 +57,7 @@ impl<'d, C: Channel> Ppi<'d, C> { /// 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) { - let r = unsafe { &*PPI::ptr() }; + let r = unsafe { &*pac::PPI::ptr() }; r.fork[self.ch.number()] .tep .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) @@ -72,7 +66,7 @@ impl<'d, C: Channel> Ppi<'d, C> { #[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() }; + let r = unsafe { &*pac::PPI::ptr() }; r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) } @@ -100,7 +94,7 @@ impl<'d, C: Channel> Drop for Ppi<'d, C> { impl<'d, C: ConfigurableChannel> Ppi<'d, C> { /// Sets the task to be triggered when the configured event occurs. pub fn set_task(&mut self, task: Task) { - let r = unsafe { &*PPI::ptr() }; + let r = unsafe { &*pac::PPI::ptr() }; r.ch[self.ch.number()] .tep .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) @@ -108,7 +102,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C> { /// Sets the event that will trigger the chosen task(s). pub fn set_event(&mut self, event: Event) { - let r = unsafe { &*PPI::ptr() }; + let r = unsafe { &*pac::PPI::ptr() }; r.ch[self.ch.number()] .eep .write(|w| unsafe { w.bits(event.0.as_ptr() as u32) }) diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 1bafb1d48..5e996e882 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -11,11 +11,6 @@ use crate::gpio::OptionalPin as GpioOptionalPin; use crate::interrupt::Interrupt; use crate::pac; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::pwm0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::pwm0_ns as pwm0; - #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub enum Prescaler { Div1, @@ -208,7 +203,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static pwm0::RegisterBlock; + fn regs() -> &'static pac::pwm0::RegisterBlock; fn state() -> &'static State; } } @@ -220,7 +215,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_pwm { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::pwm::sealed::Instance for peripherals::$type { - fn regs() -> &'static crate::pwm::pwm0::RegisterBlock { + fn regs() -> &'static pac::pwm0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::pwm::sealed::State { diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index b1d8faac8..2ce7ef16d 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -12,10 +12,7 @@ use futures::future::poll_fn; use crate::interrupt; use crate::{pac, peripherals}; -#[cfg(not(feature = "nrf9160"))] use pac::{saadc, SAADC}; -#[cfg(feature = "nrf9160")] -use pac::{saadc_ns as saadc, SAADC_NS as SAADC}; pub use saadc::{ ch::{ diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index f40da54e5..e88fb460c 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -17,13 +17,8 @@ use crate::gpio::{OptionalPin, Pin as GpioPin}; use crate::interrupt::Interrupt; use crate::{pac, util::slice_in_ram_or}; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::spim0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::spim0_ns as spim0; - pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -pub use spim0::frequency::FREQUENCY_A as Frequency; +pub use pac::spim0::frequency::FREQUENCY_A as Frequency; #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -381,7 +376,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static spim0::RegisterBlock; + fn regs() -> &'static pac::spim0::RegisterBlock; fn state() -> &'static State; } } @@ -393,7 +388,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_spim { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::spim::sealed::Instance for peripherals::$type { - fn regs() -> &'static crate::spim::spim0::RegisterBlock { + fn regs() -> &'static pac::spim0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::spim::sealed::State { diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 4c2438a00..19356c2d2 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs @@ -9,20 +9,8 @@ use embassy::time::driver::{AlarmHandle, Driver}; use crate::interrupt; use crate::pac; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::rtc0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::rtc0_ns as rtc0; - -fn rtc() -> &'static rtc0::RegisterBlock { - #[cfg(not(feature = "nrf9160"))] - unsafe { - &*pac::RTC1::ptr() - } - #[cfg(feature = "nrf9160")] - unsafe { - &*pac::RTC1_NS::ptr() - } +fn rtc() -> &'static pac::rtc0::RegisterBlock { + unsafe { &*pac::RTC1::ptr() } } // RTC timekeeping works with something we call "periods", which are time intervals diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 066609ec6..5690ff0d8 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -15,11 +15,6 @@ use crate::pac; use crate::ppi::Event; use crate::ppi::Task; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::timer0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::timer0_ns as timer0; - pub(crate) mod sealed { use super::*; @@ -27,7 +22,7 @@ pub(crate) mod sealed { pub trait Instance { /// The number of CC registers this instance has. const CCS: usize; - fn regs() -> &'static timer0::RegisterBlock; + fn regs() -> &'static pac::timer0::RegisterBlock; /// Storage for the waker for CC register `n`. fn waker(n: usize) -> &'static AtomicWaker; } @@ -45,8 +40,8 @@ macro_rules! impl_timer { ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => { impl crate::timer::sealed::Instance for peripherals::$type { const CCS: usize = $ccs; - fn regs() -> &'static crate::timer::timer0::RegisterBlock { - unsafe { &*(pac::$pac_type::ptr() as *const crate::timer::timer0::RegisterBlock) } + fn regs() -> &'static pac::timer0::RegisterBlock { + unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } } fn waker(n: usize) -> &'static ::embassy::waitqueue::AtomicWaker { use ::embassy::waitqueue::AtomicWaker; diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 8dcfb4143..8173f66b0 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -24,11 +24,6 @@ use crate::gpio::Pin as GpioPin; use crate::pac; use crate::util::{slice_in_ram, slice_in_ram_or}; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::twim0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::twim0_ns as twim0; - pub enum Frequency { #[doc = "26738688: 100 kbps"] K100 = 26738688, @@ -726,7 +721,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static twim0::RegisterBlock; + fn regs() -> &'static pac::twim0::RegisterBlock; fn state() -> &'static State; } } @@ -738,7 +733,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static { macro_rules! impl_twim { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::twim::sealed::Instance for peripherals::$type { - fn regs() -> &'static crate::twim::twim0::RegisterBlock { + fn regs() -> &'static pac::twim0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::twim::sealed::State { diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 286e324b0..320426060 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -22,13 +22,8 @@ use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::Instance as TimerInstance; use crate::timer::{Frequency, Timer}; -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::uarte0; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::uarte0_ns as uarte0; - // Re-export SVD variants to allow user to directly set values. -pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; +pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; #[non_exhaustive] pub struct Config { @@ -463,7 +458,7 @@ pub(crate) mod sealed { } pub trait Instance { - fn regs() -> &'static uarte0::RegisterBlock; + fn regs() -> &'static pac::uarte0::RegisterBlock; fn state() -> &'static State; } } @@ -475,7 +470,7 @@ pub trait Instance: Unborrow + sealed::Instance + 'static + Send macro_rules! impl_uarte { ($type:ident, $pac_type:ident, $irq:ident) => { impl crate::uarte::sealed::Instance for peripherals::$type { - fn regs() -> &'static crate::uarte::uarte0::RegisterBlock { + fn regs() -> &'static pac::uarte0::RegisterBlock { unsafe { &*pac::$pac_type::ptr() } } fn state() -> &'static crate::uarte::sealed::State { diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index 98ddd71af..eddfa7582 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs @@ -3,13 +3,7 @@ //! This HAL implements a basic watchdog timer with 1..=8 handles. //! Once the watchdog has been started, it cannot be stopped. -use crate::pac; - -#[cfg(not(feature = "nrf9160"))] -pub(crate) use pac::WDT; -#[cfg(feature = "nrf9160")] -pub(crate) use pac::WDT_NS as WDT; - +use crate::pac::WDT; use crate::peripherals; const MIN_TICKS: u32 = 15; From ddcee446c1da46b00d2088cfa1f75481b1737cc7 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 12 Oct 2021 13:35:08 +0200 Subject: [PATCH 5/6] Added anomaly workaround from the HAL to improve the UARTE --- embassy-nrf/src/uarte.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 320426060..15ebcdd57 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -114,6 +114,7 @@ impl<'d, T: Instance> Uarte<'d, T> { irq.enable(); // Enable + Self::apply_workaround_for_enable_anomaly(); r.enable.write(|w| w.enable().enabled()); Self { @@ -121,6 +122,61 @@ impl<'d, T: Instance> Uarte<'d, T> { } } + #[cfg(not(any(feature = "nrf9160", feature = "nrf5340")))] + fn apply_workaround_for_enable_anomaly() { + // Do nothing + } + + #[cfg(any(feature = "nrf9160", feature = "nrf5340"))] + fn apply_workaround_for_enable_anomaly() { + use core::ops::Deref; + + let r = T::regs(); + + // Apply workaround for anomalies: + // - nRF9160 - anomaly 23 + // - nRF5340 - anomaly 44 + let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32; + let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32; + + // NB Safety: This is taken from Nordic's driver - + // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 + if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { + r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); + } + + // NB Safety: This is taken from Nordic's driver - + // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 + if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { + r.enable.write(|w| w.enable().enabled()); + r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); + + let mut workaround_succeded = false; + // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. + // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured + // (resulting in 12 bits per data byte sent), this may take up to 40 ms. + for _ in 0..40000 { + // NB Safety: This is taken from Nordic's driver - + // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 + if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 { + workaround_succeded = true; + break; + } else { + // Need to sleep for 1us here + } + } + + if !workaround_succeded { + panic!("Failed to apply workaround for UART"); + } + + let errors = r.errorsrc.read().bits(); + // NB Safety: safe to write back the bits we just read to clear them + r.errorsrc.write(|w| unsafe { w.bits(errors) }); + r.enable.write(|w| w.enable().disabled()); + } + } + fn on_interrupt(_: *mut ()) { let r = T::regs(); let s = T::state(); From c1c704bfc82c5cbe53a00dfe9e9d1d05ab365698 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Wed, 13 Oct 2021 15:00:08 +0200 Subject: [PATCH 6/6] - Removed the enable assert from UARTE. - Added nRF9160 to CI. --- .github/workflows/rust.yml | 3 +++ embassy-nrf/src/uarte.rs | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b728c0db8..fed33cc86 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -48,6 +48,9 @@ jobs: - package: embassy-nrf target: thumbv7em-none-eabi features: nrf52833 + - package: embassy-nrf + target: thumbv8m.main-none-eabihf + features: nrf9160 - package: embassy-nrf target: thumbv7em-none-eabi features: nrf52840 diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 15ebcdd57..024a86c91 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -68,8 +68,6 @@ impl<'d, T: Instance> Uarte<'d, T> { let r = T::regs(); - assert!(r.enable.read().enable().is_disabled()); - rxd.conf().write(|w| w.input().connect().drive().h0h1()); r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });