From 663141b4e456bbfacaaff8decdba6840c76a136b Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 28 Oct 2021 03:07:06 +0200 Subject: [PATCH] nrf: add initial nrf5340 support --- .github/workflows/rust.yml | 9 + embassy-net/src/stack.rs | 1 + embassy-nrf/Cargo.toml | 22 +- embassy-nrf/src/chips/nrf5340_app.rs | 506 +++++++++++++++++++++++++++ embassy-nrf/src/chips/nrf5340_net.rs | 353 +++++++++++++++++++ embassy-nrf/src/chips/nrf9160.rs | 32 +- embassy-nrf/src/gpio.rs | 23 +- embassy-nrf/src/gpiote.rs | 81 +++-- embassy-nrf/src/lib.rs | 27 +- embassy-nrf/src/ppi/dppi.rs | 22 ++ embassy-nrf/src/ppi/mod.rs | 20 +- embassy-nrf/src/ppi/ppi.rs | 28 +- 12 files changed, 1038 insertions(+), 86 deletions(-) create mode 100644 embassy-nrf/src/chips/nrf5340_app.rs create mode 100644 embassy-nrf/src/chips/nrf5340_net.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4415fd987..8a80266be 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -60,6 +60,15 @@ jobs: - package: embassy-nrf target: thumbv8m.main-none-eabihf features: nrf9160-ns + - package: embassy-nrf + target: thumbv8m.main-none-eabihf + features: nrf5340-app-s + - package: embassy-nrf + target: thumbv8m.main-none-eabihf + features: nrf5340-app-ns + - package: embassy-nrf + target: thumbv8m.main-none-eabihf + features: nrf5340-net - package: embassy-nrf target: thumbv7em-none-eabi features: nrf52840 diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs index 42defdcaf..4faf94953 100644 --- a/embassy-net/src/stack.rs +++ b/embassy-net/src/stack.rs @@ -75,6 +75,7 @@ impl Stack { f(stack) } + #[allow(clippy::absurd_extreme_comparisons)] pub fn get_local_port(&mut self) -> u16 { let res = self.next_local_port; self.next_local_port = if res >= LOCAL_PORT_MAX { diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 479e2f912..16d3070c1 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -23,21 +23,30 @@ nrf52810 = ["nrf52810-pac", "_ppi"] nrf52811 = ["nrf52811-pac", "_ppi"] nrf52820 = ["nrf52820-pac", "_ppi"] nrf52832 = ["nrf52832-pac", "_ppi"] -nrf52833 = ["nrf52833-pac", "_ppi"] -nrf52840 = ["nrf52840-pac", "_ppi"] +nrf52833 = ["nrf52833-pac", "_ppi", "_gpio-p1"] +nrf52840 = ["nrf52840-pac", "_ppi", "_gpio-p1"] +nrf5340-app-s = ["_nrf5340-app"] +nrf5340-app-ns = ["_nrf5340-app"] +nrf5340-net = ["_nrf5340-net"] nrf9160-s = ["_nrf9160"] nrf9160-ns = ["_nrf9160"] +gpiote = [] +time-driver-rtc1 = ["_time-driver"] + # 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. +_nrf5340-app = ["_nrf5340", "nrf5340-app-pac"] +_nrf5340-net = ["_nrf5340", "nrf5340-net-pac"] +_nrf5340 = ["_gpio-p1", "_dppi"] _nrf9160 = ["nrf9160-pac", "_dppi"] + _time-driver = ["embassy/time-tick-32768hz"] + _ppi = [] _dppi = [] - -gpiote = [] -time-driver-rtc1 = ["_time-driver"] +_gpio-p1 = [] [dependencies] embassy = { version = "0.1.0", path = "../embassy" } @@ -55,6 +64,7 @@ critical-section = "0.2.3" rand_core = "0.6.3" fixed = "1.10.0" embedded-storage = "0.2.0" +cfg-if = "1.0.0" nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } @@ -63,4 +73,6 @@ 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" ] } +nrf5340-app-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } +nrf5340-net-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/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs new file mode 100644 index 000000000..ca761893f --- /dev/null +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -0,0 +1,506 @@ +#[allow(unused_imports)] +#[rustfmt::skip] +pub mod pac { + // The nRF5340 has a secure and non-secure (NS) mode. + // To avoid cfg spam, we remove _ns or _s suffixes here. + + pub use nrf5340_app_pac::{ + interrupt, + Interrupt, + Peripherals, + + cache_s as cache, + cachedata_s as cachedata, + cacheinfo_s as cacheinfo, + clock_ns as clock, + comp_ns as comp, + cryptocell_s as cryptocell, + cti_s as cti, + ctrlap_ns as ctrlap, + dcnf_ns as dcnf, + dppic_ns as dppic, + egu0_ns as egu0, + ficr_s as ficr, + fpu_ns as fpu, + gpiote0_s as gpiote, + i2s0_ns as i2s0, + ipc_ns as ipc, + kmu_ns as kmu, + lpcomp_ns as lpcomp, + mutex_ns as mutex, + nfct_ns as nfct, + nvmc_ns as nvmc, + oscillators_ns as oscillators, + p0_ns as p0, + pdm0_ns as pdm0, + power_ns as power, + pwm0_ns as pwm0, + qdec0_ns as qdec0, + qspi_ns as qspi, + regulators_ns as regulators, + reset_ns as reset, + rtc0_ns as rtc0, + saadc_ns as saadc, + spim0_ns as spim0, + spis0_ns as spis0, + spu_s as spu, + tad_s as tad, + timer0_ns as timer0, + twim0_ns as twim0, + twis0_ns as twis0, + uarte0_ns as uarte0, + uicr_s as uicr, + usbd_ns as usbd, + usbregulator_ns as usbregulator, + vmc_ns as vmc, + wdt0_ns as wdt0, + }; + + #[cfg(feature = "nrf5340-app-ns")] + pub use nrf5340_app_pac::{ + CLOCK_NS as CLOCK, + COMP_NS as COMP, + CTRLAP_NS as CTRLAP, + DCNF_NS as DCNF, + DPPIC_NS as DPPIC, + EGU0_NS as EGU0, + EGU1_NS as EGU1, + EGU2_NS as EGU2, + EGU3_NS as EGU3, + EGU4_NS as EGU4, + EGU5_NS as EGU5, + FPU_NS as FPU, + GPIOTE1_NS as GPIOTE1, + I2S0_NS as I2S0, + IPC_NS as IPC, + KMU_NS as KMU, + LPCOMP_NS as LPCOMP, + MUTEX_NS as MUTEX, + NFCT_NS as NFCT, + NVMC_NS as NVMC, + OSCILLATORS_NS as OSCILLATORS, + P0_NS as P0, + P1_NS as P1, + PDM0_NS as PDM0, + POWER_NS as POWER, + PWM0_NS as PWM0, + PWM1_NS as PWM1, + PWM2_NS as PWM2, + PWM3_NS as PWM3, + QDEC0_NS as QDEC0, + QDEC1_NS as QDEC1, + QSPI_NS as QSPI, + REGULATORS_NS as REGULATORS, + RESET_NS as RESET, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SAADC_NS as SAADC, + SPIM0_NS as SPIM0, + SPIM1_NS as SPIM1, + SPIM2_NS as SPIM2, + SPIM3_NS as SPIM3, + SPIM4_NS as SPIM4, + SPIS0_NS as SPIS0, + SPIS1_NS as SPIS1, + SPIS2_NS as SPIS2, + SPIS3_NS as SPIS3, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TWIM0_NS as TWIM0, + TWIM1_NS as TWIM1, + TWIM2_NS as TWIM2, + TWIM3_NS as TWIM3, + TWIS0_NS as TWIS0, + TWIS1_NS as TWIS1, + TWIS2_NS as TWIS2, + TWIS3_NS as TWIS3, + UARTE0_NS as UARTE0, + UARTE1_NS as UARTE1, + UARTE2_NS as UARTE2, + UARTE3_NS as UARTE3, + USBD_NS as USBD, + USBREGULATOR_NS as USBREGULATOR, + VMC_NS as VMC, + WDT0_NS as WDT0, + WDT1_NS as WDT1, + }; + + #[cfg(feature = "nrf5340-app-s")] + pub use nrf5340_app_pac::{ + CACHEDATA_S as CACHEDATA, + CACHEINFO_S as CACHEINFO, + CACHE_S as CACHE, + CLOCK_S as CLOCK, + COMP_S as COMP, + CRYPTOCELL_S as CRYPTOCELL, + CTI_S as CTI, + CTRLAP_S as CTRLAP, + DCNF_S as DCNF, + DPPIC_S as DPPIC, + EGU0_S as EGU0, + EGU1_S as EGU1, + EGU2_S as EGU2, + EGU3_S as EGU3, + EGU4_S as EGU4, + EGU5_S as EGU5, + FICR_S as FICR, + FPU_S as FPU, + GPIOTE0_S as GPIOTE0, + I2S0_S as I2S0, + IPC_S as IPC, + KMU_S as KMU, + LPCOMP_S as LPCOMP, + MUTEX_S as MUTEX, + NFCT_S as NFCT, + NVMC_S as NVMC, + OSCILLATORS_S as OSCILLATORS, + P0_S as P0, + P1_S as P1, + PDM0_S as PDM0, + POWER_S as POWER, + PWM0_S as PWM0, + PWM1_S as PWM1, + PWM2_S as PWM2, + PWM3_S as PWM3, + QDEC0_S as QDEC0, + QDEC1_S as QDEC1, + QSPI_S as QSPI, + REGULATORS_S as REGULATORS, + RESET_S as RESET, + RTC0_S as RTC0, + RTC1_S as RTC1, + SAADC_S as SAADC, + SPIM0_S as SPIM0, + SPIM1_S as SPIM1, + SPIM2_S as SPIM2, + SPIM3_S as SPIM3, + SPIM4_S as SPIM4, + SPIS0_S as SPIS0, + SPIS1_S as SPIS1, + SPIS2_S as SPIS2, + SPIS3_S as SPIS3, + SPU_S as SPU, + TAD_S as TAD, + TIMER0_S as TIMER0, + TIMER1_S as TIMER1, + TIMER2_S as TIMER2, + TWIM0_S as TWIM0, + TWIM1_S as TWIM1, + TWIM2_S as TWIM2, + TWIM3_S as TWIM3, + TWIS0_S as TWIS0, + TWIS1_S as TWIS1, + TWIS2_S as TWIS2, + TWIS3_S as TWIS3, + UARTE0_S as UARTE0, + UARTE1_S as UARTE1, + UARTE2_S as UARTE2, + UARTE3_S as UARTE3, + UICR_S as UICR, + USBD_S as USBD, + USBREGULATOR_S as USBREGULATOR, + VMC_S as VMC, + WDT0_S as WDT0, + WDT1_S as WDT1, + }; +} + +/// The maximum buffer size that the EasyDMA can send/recv in one operation. +pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; +pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; + +embassy_hal_common::peripherals! { + // RTC + RTC0, + RTC1, + + // WDT + WDT, + + // UARTE, TWI & SPI + UARTETWISPI0, + UARTETWISPI1, + UARTETWISPI2, + UARTETWISPI3, + + // 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_CH16, + PPI_CH17, + PPI_CH18, + PPI_CH19, + PPI_CH20, + PPI_CH21, + PPI_CH22, + PPI_CH23, + PPI_CH24, + PPI_CH25, + PPI_CH26, + PPI_CH27, + PPI_CH28, + PPI_CH29, + PPI_CH30, + PPI_CH31, + + 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, + + // GPIO port 1 + P1_00, + P1_01, + P1_02, + P1_03, + P1_04, + P1_05, + P1_06, + P1_07, + P1_08, + P1_09, + P1_10, + P1_11, + P1_12, + P1_13, + P1_14, + P1_15, +} + +impl_uarte!(UARTETWISPI0, UARTE0, SERIAL0); +impl_uarte!(UARTETWISPI1, UARTE1, SERIAL1); +impl_uarte!(UARTETWISPI2, UARTE2, SERIAL2); +impl_uarte!(UARTETWISPI3, UARTE3, SERIAL3); + +impl_spim!(UARTETWISPI0, SPIM0, SERIAL0); +impl_spim!(UARTETWISPI1, SPIM1, SERIAL1); +impl_spim!(UARTETWISPI2, SPIM2, SERIAL2); +impl_spim!(UARTETWISPI3, SPIM3, SERIAL3); + +impl_twim!(UARTETWISPI0, TWIM0, SERIAL0); +impl_twim!(UARTETWISPI1, TWIM1, SERIAL1); +impl_twim!(UARTETWISPI2, TWIM2, SERIAL2); +impl_twim!(UARTETWISPI3, TWIM3, SERIAL3); + +impl_pwm!(PWM0, PWM0, PWM0); +impl_pwm!(PWM1, PWM1, PWM1); +impl_pwm!(PWM2, PWM2, PWM2); +impl_pwm!(PWM3, PWM3, PWM3); + +impl_timer!(TIMER0, TIMER0, TIMER0); +impl_timer!(TIMER1, TIMER1, TIMER1); +impl_timer!(TIMER2, TIMER2, 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); + +impl_pin!(P1_00, 1, 0); +impl_pin!(P1_01, 1, 1); +impl_pin!(P1_02, 1, 2); +impl_pin!(P1_03, 1, 3); +impl_pin!(P1_04, 1, 4); +impl_pin!(P1_05, 1, 5); +impl_pin!(P1_06, 1, 6); +impl_pin!(P1_07, 1, 7); +impl_pin!(P1_08, 1, 8); +impl_pin!(P1_09, 1, 9); +impl_pin!(P1_10, 1, 10); +impl_pin!(P1_11, 1, 11); +impl_pin!(P1_12, 1, 12); +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 => configurable); +impl_ppi_channel!(PPI_CH21, 21 => configurable); +impl_ppi_channel!(PPI_CH22, 22 => configurable); +impl_ppi_channel!(PPI_CH23, 23 => configurable); +impl_ppi_channel!(PPI_CH24, 24 => configurable); +impl_ppi_channel!(PPI_CH25, 25 => configurable); +impl_ppi_channel!(PPI_CH26, 26 => configurable); +impl_ppi_channel!(PPI_CH27, 27 => configurable); +impl_ppi_channel!(PPI_CH28, 28 => configurable); +impl_ppi_channel!(PPI_CH29, 29 => configurable); +impl_ppi_channel!(PPI_CH30, 30 => configurable); +impl_ppi_channel!(PPI_CH31, 31 => 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; + + declare!(FPU); + declare!(CACHE); + declare!(SPU); + declare!(CLOCK_POWER); + declare!(SERIAL0); + declare!(SERIAL1); + declare!(SPIM4); + declare!(SERIAL2); + declare!(SERIAL3); + declare!(GPIOTE0); + declare!(SAADC); + declare!(TIMER0); + declare!(TIMER1); + declare!(TIMER2); + declare!(RTC0); + declare!(RTC1); + declare!(WDT0); + declare!(WDT1); + declare!(COMP_LPCOMP); + declare!(EGU0); + declare!(EGU1); + declare!(EGU2); + declare!(EGU3); + declare!(EGU4); + declare!(EGU5); + declare!(PWM0); + declare!(PWM1); + declare!(PWM2); + declare!(PWM3); + declare!(PDM0); + declare!(I2S0); + declare!(IPC); + declare!(QSPI); + declare!(NFCT); + declare!(GPIOTE1); + declare!(QDEC0); + declare!(QDEC1); + declare!(USBD); + declare!(USBREGULATOR); + declare!(KMU); + declare!(CRYPTOCELL); +} diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs new file mode 100644 index 000000000..ea09f8d78 --- /dev/null +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -0,0 +1,353 @@ +#[allow(unused_imports)] +#[rustfmt::skip] +pub mod pac { + // The nRF5340 has a secure and non-secure (NS) mode. + // To avoid cfg spam, we remove _ns or _s suffixes here. + + pub use nrf5340_net_pac::{ + interrupt, + Interrupt, + Peripherals, + + aar_ns as aar, + acl_ns as acl, + appmutex_ns as appmutex, + ccm_ns as ccm, + clock_ns as clock, + cti_ns as cti, + ctrlap_ns as ctrlap, + dcnf_ns as dcnf, + dppic_ns as dppic, + ecb_ns as ecb, + egu0_ns as egu0, + ficr_ns as ficr, + gpiote_ns as gpiote, + ipc_ns as ipc, + nvmc_ns as nvmc, + p0_ns as p0, + power_ns as power, + radio_ns as radio, + reset_ns as reset, + rng_ns as rng, + rtc0_ns as rtc0, + spim0_ns as spim0, + spis0_ns as spis0, + swi0_ns as swi0, + temp_ns as temp, + timer0_ns as timer0, + twim0_ns as twim0, + twis0_ns as twis0, + uarte0_ns as uarte0, + uicr_ns as uicr, + vmc_ns as vmc, + vreqctrl_ns as vreqctrl, + wdt_ns as wdt, + + AAR_NS as AAR, + ACL_NS as ACL, + APPMUTEX_NS as APPMUTEX, + APPMUTEX_S as APPMUTEX_S, + CBP as CBP, + CCM_NS as CCM, + CLOCK_NS as CLOCK, + CPUID as CPUID, + CTI_NS as CTI, + CTRLAP_NS as CTRLAP, + DCB as DCB, + DCNF_NS as DCNF, + DPPIC_NS as DPPIC, + DWT as DWT, + ECB_NS as ECB, + EGU0_NS as EGU0, + FICR_NS as FICR, + FPB as FPB, + GPIOTE_NS as GPIOTE, + IPC_NS as IPC, + ITM as ITM, + MPU as MPU, + NVIC as NVIC, + NVMC_NS as NVMC, + P0_NS as P0, + P1_NS as P1, + POWER_NS as POWER, + RADIO_NS as RADIO, + RESET_NS as RESET, + RNG_NS as RNG, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SCB as SCB, + SPIM0_NS as SPIM0, + SPIS0_NS as SPIS0, + SWI0_NS as SWI0, + SWI1_NS as SWI1, + SWI2_NS as SWI2, + SWI3_NS as SWI3, + SYST as SYST, + TEMP_NS as TEMP, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TPIU as TPIU, + TWIM0_NS as TWIM0, + TWIS0_NS as TWIS0, + UARTE0_NS as UARTE0, + UICR_NS as UICR, + VMC_NS as VMC, + VREQCTRL_NS as VREQCTRL, + WDT_NS as WDT, + }; + +} + +/// The maximum buffer size that the EasyDMA can send/recv in one operation. +pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; +pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; + +embassy_hal_common::peripherals! { + // RTC + RTC0, + RTC1, + + // WDT + WDT, + + // UARTE, TWI & SPI + UARTETWISPI0, + UARTETWISPI1, + UARTETWISPI2, + UARTETWISPI3, + + // 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_CH16, + PPI_CH17, + PPI_CH18, + PPI_CH19, + PPI_CH20, + PPI_CH21, + PPI_CH22, + PPI_CH23, + PPI_CH24, + PPI_CH25, + PPI_CH26, + PPI_CH27, + PPI_CH28, + PPI_CH29, + PPI_CH30, + PPI_CH31, + + 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, + + // GPIO port 1 + P1_00, + P1_01, + P1_02, + P1_03, + P1_04, + P1_05, + P1_06, + P1_07, + P1_08, + P1_09, + P1_10, + P1_11, + P1_12, + P1_13, + P1_14, + P1_15, +} + +impl_uarte!(UARTETWISPI0, UARTE0, SERIAL0); +impl_spim!(UARTETWISPI0, SPIM0, SERIAL0); +impl_twim!(UARTETWISPI0, TWIM0, SERIAL0); + +impl_timer!(TIMER0, TIMER0, TIMER0); +impl_timer!(TIMER1, TIMER1, TIMER1); +impl_timer!(TIMER2, TIMER2, 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); + +impl_pin!(P1_00, 1, 0); +impl_pin!(P1_01, 1, 1); +impl_pin!(P1_02, 1, 2); +impl_pin!(P1_03, 1, 3); +impl_pin!(P1_04, 1, 4); +impl_pin!(P1_05, 1, 5); +impl_pin!(P1_06, 1, 6); +impl_pin!(P1_07, 1, 7); +impl_pin!(P1_08, 1, 8); +impl_pin!(P1_09, 1, 9); +impl_pin!(P1_10, 1, 10); +impl_pin!(P1_11, 1, 11); +impl_pin!(P1_12, 1, 12); +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 => configurable); +impl_ppi_channel!(PPI_CH21, 21 => configurable); +impl_ppi_channel!(PPI_CH22, 22 => configurable); +impl_ppi_channel!(PPI_CH23, 23 => configurable); +impl_ppi_channel!(PPI_CH24, 24 => configurable); +impl_ppi_channel!(PPI_CH25, 25 => configurable); +impl_ppi_channel!(PPI_CH26, 26 => configurable); +impl_ppi_channel!(PPI_CH27, 27 => configurable); +impl_ppi_channel!(PPI_CH28, 28 => configurable); +impl_ppi_channel!(PPI_CH29, 29 => configurable); +impl_ppi_channel!(PPI_CH30, 30 => configurable); +impl_ppi_channel!(PPI_CH31, 31 => configurable); + +pub mod irqs { + use crate::pac::Interrupt as InterruptEnum; + use embassy_macros::interrupt_declare as declare; + + declare!(CLOCK_POWER); + declare!(RADIO); + declare!(RNG); + declare!(GPIOTE); + declare!(WDT); + declare!(TIMER0); + declare!(ECB); + declare!(AAR_CCM); + declare!(TEMP); + declare!(RTC0); + declare!(IPC); + declare!(SERIAL0); + declare!(EGU0); + declare!(RTC1); + declare!(TIMER1); + declare!(TIMER2); + declare!(SWI0); + declare!(SWI1); + declare!(SWI2); + declare!(SWI3); +} diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 3db1e77f2..3678e6d31 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -2,27 +2,49 @@ #[rustfmt::skip] 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. + // To avoid cfg spam, we remove _ns or _s suffixes here. pub use nrf9160_pac::{ interrupt, Interrupt, + cc_host_rgf_s as cc_host_rgf, + clock_ns as clock, + cryptocell_s as cryptocell, + ctrl_ap_peri_s as ctrl_ap_peri, + dppic_ns as dppic, + egu0_ns as egu0, + ficr_s as ficr, + fpu_ns as fpu, + gpiote0_s as gpiote0, + i2s_ns as i2s, + ipc_ns as ipc, + kmu_ns as kmu, + nvmc_ns as nvmc, p0_ns as p0, + pdm_ns as pdm, + power_ns as power, pwm0_ns as pwm0, + regulators_ns as regulators, rtc0_ns as rtc0, + saadc_ns as saadc, spim0_ns as spim0, + spis0_ns as spis0, + spu_s as spu, + tad_s as tad, timer0_ns as timer0, twim0_ns as twim0, + twis0_ns as twis0, uarte0_ns as uarte0, - saadc_ns as saadc, + uicr_s as uicr, + vmc_ns as vmc, + wdt_ns as wdt, }; #[cfg(feature = "nrf9160-ns")] pub use nrf9160_pac::{ CLOCK_NS as CLOCK, - DPPIC_NS as PPI, + DPPIC_NS as DPPIC, EGU0_NS as EGU0, EGU1_NS as EGU1, EGU2_NS as EGU2, @@ -79,7 +101,7 @@ pub mod pac { CLOCK_S as CLOCK, CRYPTOCELL_S as CRYPTOCELL, CTRL_AP_PERI_S as CTRL_AP_PERI, - DPPIC_S as PPI, + DPPIC_S as DPPIC, EGU0_S as EGU0, EGU1_S as EGU1, EGU2_S as EGU2, diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 7896945fb..91b2e585a 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -4,6 +4,7 @@ use core::convert::Infallible; use core::hint::unreachable_unchecked; use core::marker::PhantomData; +use cfg_if::cfg_if; use embassy::util::Unborrow; use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; @@ -20,8 +21,8 @@ pub enum Port { /// Port 0, available on nRF9160 and all nRF52 and nRF51 MCUs. Port0, - /// Port 1, only available on some nRF52 MCUs. - #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] + /// Port 1, only available on some MCUs. + #[cfg(feature = "_gpio-p1")] Port1, } @@ -284,14 +285,12 @@ pub(crate) mod sealed { #[inline] fn _pin(&self) -> u8 { - #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] - { - self.pin_port() % 32 - } - - #[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))] - { - self.pin_port() + cfg_if! { + if #[cfg(feature = "_gpio-p1")] { + self.pin_port() % 32 + } else { + self.pin_port() + } } } @@ -300,7 +299,7 @@ pub(crate) mod sealed { unsafe { match self.pin_port() / 32 { 0 => &*pac::P0::ptr(), - #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] + #[cfg(feature = "_gpio-p1")] 1 => &*pac::P1::ptr(), _ => unreachable_unchecked(), } @@ -344,7 +343,7 @@ pub trait Pin: Unborrow + sealed::Pin + Sized + 'static { fn port(&self) -> Port { match self.pin_port() / 32 { 0 => Port::Port0, - #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] + #[cfg(feature = "_gpio-p1")] 1 => Port::Port1, _ => unsafe { unreachable_unchecked() }, } diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 03688859f..ee638aeac 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -41,6 +41,18 @@ pub enum OutputChannelPolarity { Toggle, } +fn regs() -> &'static pac::gpiote::RegisterBlock { + cfg_if::cfg_if! { + if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s"))] { + unsafe { &*pac::GPIOTE0::ptr() } + } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns"))] { + unsafe { &*pac::GPIOTE1::ptr() } + } else { + unsafe { &*pac::GPIOTE::ptr() } + } + } +} + pub(crate) fn init(irq_prio: crate::interrupt::Priority) { #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; @@ -55,35 +67,46 @@ 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() }; + cfg_if::cfg_if! { + if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s"))] { + let irq = unsafe { interrupt::GPIOTE0::steal() }; + } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns"))] { + let irq = unsafe { interrupt::GPIOTE1::steal() }; + } else { + let irq = unsafe { interrupt::GPIOTE::steal() }; + } + } irq.unpend(); irq.set_priority(irq_prio); irq.enable(); - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = regs(); g.events_port.write(|w| w); g.intenset.write(|w| w.port().set()); } -#[cfg(not(feature = "_nrf9160"))] -#[interrupt] -fn GPIOTE() { - unsafe { handle_gpiote_interrupt() }; -} - -#[cfg(feature = "_nrf9160")] -#[interrupt] -fn GPIOTE1() { - unsafe { handle_gpiote_interrupt() }; +cfg_if::cfg_if! { + if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s"))] { + #[interrupt] + fn GPIOTE0() { + unsafe { handle_gpiote_interrupt() }; + } + } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns"))] { + #[interrupt] + fn GPIOTE1() { + unsafe { handle_gpiote_interrupt() }; + } + } else { + #[interrupt] + fn GPIOTE() { + unsafe { handle_gpiote_interrupt() }; + } + } } unsafe fn handle_gpiote_interrupt() { - let g = &*pac::GPIOTE::ptr(); + let g = regs(); for i in 0..CHANNEL_COUNT { if g.events_in[i].read().bits() != 0 { @@ -135,7 +158,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 = regs(); let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -144,7 +167,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 = regs(); let num = ch.number(); g.config[num].write(|w| { @@ -168,7 +191,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> { } pub async fn wait(&self) { - let g = unsafe { &*pac::GPIOTE::ptr() }; + let g = regs(); let num = self.ch.number(); // Enable interrupt @@ -189,7 +212,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 = regs(); Event::from_reg(&g.events_in[self.ch.number()]) } } @@ -214,7 +237,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 = regs(); let num = self.ch.number(); g.config[num].write(|w| w.mode().disabled()); g.intenclr.write(|w| unsafe { w.bits(1 << num) }); @@ -223,7 +246,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 = regs(); let num = ch.number(); g.config[num].write(|w| { @@ -250,41 +273,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 = regs(); 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 { &*pac::GPIOTE::ptr() }; + let g = regs(); 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 { &*pac::GPIOTE::ptr() }; + let g = regs(); 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 = regs(); 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 { &*pac::GPIOTE::ptr() }; + let g = regs(); 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 { &*pac::GPIOTE::ptr() }; + let g = regs(); Task::from_reg(&g.tasks_set[self.ch.number()]) } } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 05bdd1904..5a73b87e0 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -12,7 +12,8 @@ feature = "nrf52832", feature = "nrf52833", feature = "nrf52840", - feature = "nrf5340-app", + feature = "nrf5340-app-s", + feature = "nrf5340-app-ns", feature = "nrf5340-net", feature = "nrf9160-s", feature = "nrf9160-ns", @@ -30,23 +31,24 @@ pub mod buffered_uarte; pub mod gpio; #[cfg(feature = "gpiote")] pub mod gpiote; -#[cfg(not(feature = "_nrf9160"))] +#[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] pub mod nvmc; pub mod ppi; -#[cfg(not(any(feature = "nrf52805", feature = "nrf52820")))] +#[cfg(not(any(feature = "nrf52805", feature = "nrf52820", feature = "_nrf5340-net")))] pub mod pwm; #[cfg(feature = "nrf52840")] pub mod qspi; -#[cfg(not(feature = "_nrf9160"))] +#[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] pub mod rng; -#[cfg(not(feature = "nrf52820"))] +#[cfg(not(any(feature = "nrf52820", feature = "_nrf5340-net")))] pub mod saadc; pub mod spim; -#[cfg(not(feature = "_nrf9160"))] +#[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] pub mod temp; pub mod timer; pub mod twim; pub mod uarte; +#[cfg(not(feature = "_nrf5340"))] pub mod wdt; // This mod MUST go last, so that it sees all the `impl_foo!` macros @@ -57,6 +59,8 @@ pub mod wdt; #[cfg_attr(feature = "nrf52832", path = "chips/nrf52832.rs")] #[cfg_attr(feature = "nrf52833", path = "chips/nrf52833.rs")] #[cfg_attr(feature = "nrf52840", path = "chips/nrf52840.rs")] +#[cfg_attr(feature = "_nrf5340-app", path = "chips/nrf5340_app.rs")] +#[cfg_attr(feature = "_nrf5340-net", path = "chips/nrf5340_net.rs")] #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] mod chip; @@ -67,7 +71,6 @@ pub use chip::pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use chip::pac; -use crate::pac::CLOCK; pub use chip::{peripherals, Peripherals}; pub mod interrupt { @@ -86,12 +89,12 @@ pub mod config { pub enum LfclkSource { InternalRC, - #[cfg(not(feature = "_nrf9160"))] + #[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] Synthesized, ExternalXtal, - #[cfg(not(feature = "_nrf9160"))] + #[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] ExternalLowSwing, - #[cfg(not(feature = "_nrf9160"))] + #[cfg(not(any(feature = "_nrf5340", feature = "_nrf9160")))] ExternalFullSwing, } @@ -127,7 +130,7 @@ pub fn init(config: config::Config) -> Peripherals { // before doing anything important. let peripherals = Peripherals::take(); - let r = unsafe { &*CLOCK::ptr() }; + let r = unsafe { &*pac::CLOCK::ptr() }; // Start HFCLK. match config.hfclk_source { @@ -141,7 +144,7 @@ pub fn init(config: config::Config) -> Peripherals { } // Configure LFCLK. - #[cfg(not(feature = "_nrf9160"))] + #[cfg(not(any(feature = "_nrf5340", 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()), diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index b3676fca4..1842590b4 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs @@ -3,11 +3,17 @@ use core::marker::PhantomData; use embassy::util::Unborrow; use embassy_hal_common::unborrow; +use crate::pac; + use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; const DPPI_ENABLE_BIT: u32 = 0x8000_0000; const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; +fn regs() -> &'static pac::dppic::RegisterBlock { + unsafe { &*pac::DPPIC::ptr() } +} + impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { Ppi::new_many_to_many(ch, [event], [task]) @@ -58,6 +64,22 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi } } +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + /// Enables the channel. + pub fn enable(&mut self) { + let n = self.ch.number(); + regs().chenset.write(|w| unsafe { w.bits(1 << n) }); + } + + /// Disables the channel. + pub fn disable(&mut self) { + let n = self.ch.number(); + regs().chenclr.write(|w| unsafe { w.bits(1 << n) }); + } +} + impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 96f867d18..aeccb154b 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -15,7 +15,7 @@ //! many tasks and events, but any single task or event can only be coupled with one channel. //! -use crate::{pac, peripherals}; +use crate::peripherals; use core::marker::PhantomData; use core::ptr::NonNull; use embassy::util::Unborrow; @@ -35,24 +35,6 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize phantom: PhantomData<&'d mut C>, } -impl<'d, C: Channel + 'd, const EVENT_COUNT: usize, const TASK_COUNT: usize> - Ppi<'d, C, EVENT_COUNT, TASK_COUNT> -{ - /// Enables the channel. - pub fn enable(&mut self) { - 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 { &*pac::PPI::ptr() }; - r.chenclr - .write(|w| unsafe { w.bits(1 << self.ch.number()) }); - } -} - const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); /// Represents a task that a peripheral can do. diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index c1d9794c9..cdbe046f8 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -17,12 +17,16 @@ impl Event { } } +fn regs() -> &'static pac::ppi::RegisterBlock { + unsafe { &*pac::PPI::ptr() } +} + #[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { pub fn new_zero_to_one(ch: impl Unborrow + 'd, task: Task) -> Self { unborrow!(ch); - let r = unsafe { &*pac::PPI::ptr() }; + let r = regs(); let n = ch.number(); r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); @@ -37,7 +41,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { pub fn new_one_to_one(ch: impl Unborrow + 'd, event: Event, task: Task) -> Self { unborrow!(ch); - let r = unsafe { &*pac::PPI::ptr() }; + let r = regs(); let n = ch.number(); r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); @@ -59,7 +63,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { ) -> Self { unborrow!(ch); - let r = unsafe { &*pac::PPI::ptr() }; + let r = regs(); let n = ch.number(); r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) }); @@ -72,13 +76,29 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { } } +impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> + Ppi<'d, C, EVENT_COUNT, TASK_COUNT> +{ + /// Enables the channel. + pub fn enable(&mut self) { + let n = self.ch.number(); + regs().chenset.write(|w| unsafe { w.bits(1 << n) }); + } + + /// Disables the channel. + pub fn disable(&mut self) { + let n = self.ch.number(); + regs().chenclr.write(|w| unsafe { w.bits(1 << n) }); + } +} + impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop for Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { fn drop(&mut self) { self.disable(); - let r = unsafe { &*pac::PPI::ptr() }; + let r = regs(); let n = self.ch.number(); r.ch[n].eep.write(|w| unsafe { w.bits(0) }); r.ch[n].tep.write(|w| unsafe { w.bits(0) });