Merge pull request #3544 from embassy-rs/nrf54l
nrf: add nrf54l base: gpio and time driver.
This commit is contained in:
		
						commit
						5c9f9c443f
					
				
							
								
								
									
										3
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ci.sh
									
									
									
									
									
								
							@ -70,6 +70,8 @@ cargo batch \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-s,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-ns,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-net,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf54l15-app-s,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf54l15-app-ns,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time-driver-rtc1 \
 | 
			
		||||
    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time,time-driver-rtc1 \
 | 
			
		||||
@ -197,6 +199,7 @@ cargo batch \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf52810/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52810 \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf54l15/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf54l15 \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf9160/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf9160 \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf9151/s/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf9151/s \
 | 
			
		||||
    --- build --release --manifest-path examples/nrf9151/ns/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf9151/ns \
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ log = [ "dep:log" ]
 | 
			
		||||
defmt = { version = "0.3", optional = true }
 | 
			
		||||
log = { version = "0.4.14", optional = true }
 | 
			
		||||
 | 
			
		||||
nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "12e2461859acb0bfea9b2ef5cd73f1283c139ac0" }
 | 
			
		||||
nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "52e3a757f06035c94291bfc42b0c03f71e4d677e" }
 | 
			
		||||
cortex-m = "0.7.7"
 | 
			
		||||
 | 
			
		||||
embassy-time = { version = "0.3.1", path = "../embassy-time" }
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,11 @@ nrf5340-app-s = ["_nrf5340-app", "_s"]
 | 
			
		||||
nrf5340-app-ns = ["_nrf5340-app", "_ns"]
 | 
			
		||||
## nRF5340 network core
 | 
			
		||||
nrf5340-net = ["_nrf5340-net"]
 | 
			
		||||
## nRF54L15 application core in Secure mode
 | 
			
		||||
nrf54l15-app-s = ["_nrf54l15-app", "_s"]
 | 
			
		||||
## nRF54L15 application core in Non-Secure mode
 | 
			
		||||
nrf54l15-app-ns = ["_nrf54l15-app", "_ns"]
 | 
			
		||||
 | 
			
		||||
## nRF9160 in Secure mode
 | 
			
		||||
nrf9160-s = ["_nrf9160", "_s", "_nrf91"]
 | 
			
		||||
## nRF9160 in Non-Secure mode
 | 
			
		||||
@ -103,6 +108,10 @@ nrf9161-ns = ["nrf9120-ns"]
 | 
			
		||||
_nrf5340-app = ["_nrf5340", "nrf-pac/nrf5340-app"]
 | 
			
		||||
_nrf5340-net = ["_nrf5340", "nrf-pac/nrf5340-net"]
 | 
			
		||||
_nrf5340 = ["_gpio-p1", "_dppi"]
 | 
			
		||||
_nrf54l15-app = ["_nrf54l15", "nrf-pac/nrf54l15-app"]
 | 
			
		||||
_nrf54l15 = ["_nrf54l", "_gpio-p1", "_gpio-p2"]
 | 
			
		||||
_nrf54l = ["_dppi"]
 | 
			
		||||
 | 
			
		||||
_nrf9160 = ["nrf-pac/nrf9160", "_dppi"]
 | 
			
		||||
_nrf9120 = ["nrf-pac/nrf9120", "_dppi"]
 | 
			
		||||
_nrf52 = ["_ppi"]
 | 
			
		||||
@ -118,6 +127,7 @@ _ns = []
 | 
			
		||||
_ppi = []
 | 
			
		||||
_dppi = []
 | 
			
		||||
_gpio-p1 = []
 | 
			
		||||
_gpio-p2 = []
 | 
			
		||||
 | 
			
		||||
# Errata workarounds
 | 
			
		||||
_nrf52832_anomaly_109 = []
 | 
			
		||||
@ -136,7 +146,7 @@ embedded-hal-async = { version = "1.0" }
 | 
			
		||||
embedded-io = { version = "0.6.0" }
 | 
			
		||||
embedded-io-async = { version = "0.6.1" }
 | 
			
		||||
 | 
			
		||||
nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "12e2461859acb0bfea9b2ef5cd73f1283c139ac0" }
 | 
			
		||||
nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "52e3a757f06035c94291bfc42b0c03f71e4d677e" }
 | 
			
		||||
 | 
			
		||||
defmt = { version = "0.3", optional = true }
 | 
			
		||||
bitflags = "2.4.2"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										346
									
								
								embassy-nrf/src/chips/nrf54l15_app.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								embassy-nrf/src/chips/nrf54l15_app.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,346 @@
 | 
			
		||||
/// Peripheral Access Crate
 | 
			
		||||
#[allow(unused_imports)]
 | 
			
		||||
#[rustfmt::skip]
 | 
			
		||||
pub mod pac {
 | 
			
		||||
    pub use nrf_pac::*;
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "_ns")]
 | 
			
		||||
    #[doc(no_inline)]
 | 
			
		||||
    pub use nrf_pac::{
 | 
			
		||||
        FICR_NS as FICR,
 | 
			
		||||
        DPPIC00_NS as DPPIC00,
 | 
			
		||||
        PPIB00_NS as PPIB00,
 | 
			
		||||
        PPIB01_NS as PPIB01,
 | 
			
		||||
        AAR00_NS as AAR00,
 | 
			
		||||
        CCM00_NS as CCM00,
 | 
			
		||||
        ECB00_NS as ECB00,
 | 
			
		||||
        SPIM00_NS as SPIM00,
 | 
			
		||||
        SPIS00_NS as SPIS00,
 | 
			
		||||
        UARTE00_NS as UARTE00,
 | 
			
		||||
        VPR00_NS as VPR00,
 | 
			
		||||
        P2_NS as P2,
 | 
			
		||||
        CTRLAP_NS as CTRLAP,
 | 
			
		||||
        TAD_NS as TAD,
 | 
			
		||||
        TIMER00_NS as TIMER00,
 | 
			
		||||
        DPPIC10_NS as DPPIC10,
 | 
			
		||||
        PPIB10_NS as PPIB10,
 | 
			
		||||
        PPIB11_NS as PPIB11,
 | 
			
		||||
        TIMER10_NS as TIMER10,
 | 
			
		||||
        RTC10_NS as RTC10,
 | 
			
		||||
        EGU10_NS as EGU10,
 | 
			
		||||
        RADIO_NS as RADIO,
 | 
			
		||||
        DPPIC20_NS as DPPIC20,
 | 
			
		||||
        PPIB20_NS as PPIB20,
 | 
			
		||||
        PPIB21_NS as PPIB21,
 | 
			
		||||
        PPIB22_NS as PPIB22,
 | 
			
		||||
        SPIM20_NS as SPIM20,
 | 
			
		||||
        SPIS20_NS as SPIS20,
 | 
			
		||||
        TWIM20_NS as TWIM20,
 | 
			
		||||
        TWIS20_NS as TWIS20,
 | 
			
		||||
        UARTE20_NS as UARTE20,
 | 
			
		||||
        SPIM21_NS as SPIM21,
 | 
			
		||||
        SPIS21_NS as SPIS21,
 | 
			
		||||
        TWIM21_NS as TWIM21,
 | 
			
		||||
        TWIS21_NS as TWIS21,
 | 
			
		||||
        UARTE21_NS as UARTE21,
 | 
			
		||||
        SPIM22_NS as SPIM22,
 | 
			
		||||
        SPIS22_NS as SPIS22,
 | 
			
		||||
        TWIM22_NS as TWIM22,
 | 
			
		||||
        TWIS22_NS as TWIS22,
 | 
			
		||||
        UARTE22_NS as UARTE22,
 | 
			
		||||
        EGU20_NS as EGU20,
 | 
			
		||||
        TIMER20_NS as TIMER20,
 | 
			
		||||
        TIMER21_NS as TIMER21,
 | 
			
		||||
        TIMER22_NS as TIMER22,
 | 
			
		||||
        TIMER23_NS as TIMER23,
 | 
			
		||||
        TIMER24_NS as TIMER24,
 | 
			
		||||
        MEMCONF_NS as MEMCONF,
 | 
			
		||||
        PDM20_NS as PDM20,
 | 
			
		||||
        PDM21_NS as PDM21,
 | 
			
		||||
        PWM20_NS as PWM20,
 | 
			
		||||
        PWM21_NS as PWM21,
 | 
			
		||||
        PWM22_NS as PWM22,
 | 
			
		||||
        SAADC_NS as SAADC,
 | 
			
		||||
        NFCT_NS as NFCT,
 | 
			
		||||
        TEMP_NS as TEMP,
 | 
			
		||||
        P1_NS as P1,
 | 
			
		||||
        GPIOTE20_NS as GPIOTE20,
 | 
			
		||||
        I2S20_NS as I2S20,
 | 
			
		||||
        QDEC20_NS as QDEC20,
 | 
			
		||||
        QDEC21_NS as QDEC21,
 | 
			
		||||
        GRTC_NS as GRTC,
 | 
			
		||||
        DPPIC30_NS as DPPIC30,
 | 
			
		||||
        PPIB30_NS as PPIB30,
 | 
			
		||||
        SPIM30_NS as SPIM30,
 | 
			
		||||
        SPIS30_NS as SPIS30,
 | 
			
		||||
        TWIM30_NS as TWIM30,
 | 
			
		||||
        TWIS30_NS as TWIS30,
 | 
			
		||||
        UARTE30_NS as UARTE30,
 | 
			
		||||
        RTC30_NS as RTC30,
 | 
			
		||||
        COMP_NS as COMP,
 | 
			
		||||
        LPCOMP_NS as LPCOMP,
 | 
			
		||||
        WDT31_NS as WDT31,
 | 
			
		||||
        P0_NS as P0,
 | 
			
		||||
        GPIOTE30_NS as GPIOTE30,
 | 
			
		||||
        CLOCK_NS as CLOCK,
 | 
			
		||||
        POWER_NS as POWER,
 | 
			
		||||
        RESET_NS as RESET,
 | 
			
		||||
        OSCILLATORS_NS as OSCILLATORS,
 | 
			
		||||
        REGULATORS_NS as REGULATORS,
 | 
			
		||||
        TPIU_NS as TPIU,
 | 
			
		||||
        ETM_NS as ETM,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "_s")]
 | 
			
		||||
    #[doc(no_inline)]
 | 
			
		||||
    pub use nrf_pac::{
 | 
			
		||||
        SICR_S as SICR,
 | 
			
		||||
        ICACHEDATA_S as ICACHEDATA,
 | 
			
		||||
        ICACHEINFO_S as ICACHEINFO,
 | 
			
		||||
        SWI00_S as SWI00,
 | 
			
		||||
        SWI01_S as SWI01,
 | 
			
		||||
        SWI02_S as SWI02,
 | 
			
		||||
        SWI03_S as SWI03,
 | 
			
		||||
        SPU00_S as SPU00,
 | 
			
		||||
        MPC00_S as MPC00,
 | 
			
		||||
        DPPIC00_S as DPPIC00,
 | 
			
		||||
        PPIB00_S as PPIB00,
 | 
			
		||||
        PPIB01_S as PPIB01,
 | 
			
		||||
        KMU_S as KMU,
 | 
			
		||||
        AAR00_S as AAR00,
 | 
			
		||||
        CCM00_S as CCM00,
 | 
			
		||||
        ECB00_S as ECB00,
 | 
			
		||||
        CRACEN_S as CRACEN,
 | 
			
		||||
        SPIM00_S as SPIM00,
 | 
			
		||||
        SPIS00_S as SPIS00,
 | 
			
		||||
        UARTE00_S as UARTE00,
 | 
			
		||||
        GLITCHDET_S as GLITCHDET,
 | 
			
		||||
        RRAMC_S as RRAMC,
 | 
			
		||||
        VPR00_S as VPR00,
 | 
			
		||||
        P2_S as P2,
 | 
			
		||||
        CTRLAP_S as CTRLAP,
 | 
			
		||||
        TAD_S as TAD,
 | 
			
		||||
        TIMER00_S as TIMER00,
 | 
			
		||||
        SPU10_S as SPU10,
 | 
			
		||||
        DPPIC10_S as DPPIC10,
 | 
			
		||||
        PPIB10_S as PPIB10,
 | 
			
		||||
        PPIB11_S as PPIB11,
 | 
			
		||||
        TIMER10_S as TIMER10,
 | 
			
		||||
        RTC10_S as RTC10,
 | 
			
		||||
        EGU10_S as EGU10,
 | 
			
		||||
        RADIO_S as RADIO,
 | 
			
		||||
        SPU20_S as SPU20,
 | 
			
		||||
        DPPIC20_S as DPPIC20,
 | 
			
		||||
        PPIB20_S as PPIB20,
 | 
			
		||||
        PPIB21_S as PPIB21,
 | 
			
		||||
        PPIB22_S as PPIB22,
 | 
			
		||||
        SPIM20_S as SPIM20,
 | 
			
		||||
        SPIS20_S as SPIS20,
 | 
			
		||||
        TWIM20_S as TWIM20,
 | 
			
		||||
        TWIS20_S as TWIS20,
 | 
			
		||||
        UARTE20_S as UARTE20,
 | 
			
		||||
        SPIM21_S as SPIM21,
 | 
			
		||||
        SPIS21_S as SPIS21,
 | 
			
		||||
        TWIM21_S as TWIM21,
 | 
			
		||||
        TWIS21_S as TWIS21,
 | 
			
		||||
        UARTE21_S as UARTE21,
 | 
			
		||||
        SPIM22_S as SPIM22,
 | 
			
		||||
        SPIS22_S as SPIS22,
 | 
			
		||||
        TWIM22_S as TWIM22,
 | 
			
		||||
        TWIS22_S as TWIS22,
 | 
			
		||||
        UARTE22_S as UARTE22,
 | 
			
		||||
        EGU20_S as EGU20,
 | 
			
		||||
        TIMER20_S as TIMER20,
 | 
			
		||||
        TIMER21_S as TIMER21,
 | 
			
		||||
        TIMER22_S as TIMER22,
 | 
			
		||||
        TIMER23_S as TIMER23,
 | 
			
		||||
        TIMER24_S as TIMER24,
 | 
			
		||||
        MEMCONF_S as MEMCONF,
 | 
			
		||||
        PDM20_S as PDM20,
 | 
			
		||||
        PDM21_S as PDM21,
 | 
			
		||||
        PWM20_S as PWM20,
 | 
			
		||||
        PWM21_S as PWM21,
 | 
			
		||||
        PWM22_S as PWM22,
 | 
			
		||||
        SAADC_S as SAADC,
 | 
			
		||||
        NFCT_S as NFCT,
 | 
			
		||||
        TEMP_S as TEMP,
 | 
			
		||||
        P1_S as P1,
 | 
			
		||||
        GPIOTE20_S as GPIOTE20,
 | 
			
		||||
        TAMPC_S as TAMPC,
 | 
			
		||||
        I2S20_S as I2S20,
 | 
			
		||||
        QDEC20_S as QDEC20,
 | 
			
		||||
        QDEC21_S as QDEC21,
 | 
			
		||||
        GRTC_S as GRTC,
 | 
			
		||||
        SPU30_S as SPU30,
 | 
			
		||||
        DPPIC30_S as DPPIC30,
 | 
			
		||||
        PPIB30_S as PPIB30,
 | 
			
		||||
        SPIM30_S as SPIM30,
 | 
			
		||||
        SPIS30_S as SPIS30,
 | 
			
		||||
        TWIM30_S as TWIM30,
 | 
			
		||||
        TWIS30_S as TWIS30,
 | 
			
		||||
        UARTE30_S as UARTE30,
 | 
			
		||||
        RTC30_S as RTC30,
 | 
			
		||||
        COMP_S as COMP,
 | 
			
		||||
        LPCOMP_S as LPCOMP,
 | 
			
		||||
        WDT30_S as WDT30,
 | 
			
		||||
        WDT31_S as WDT31,
 | 
			
		||||
        P0_S as P0,
 | 
			
		||||
        GPIOTE30_S as GPIOTE30,
 | 
			
		||||
        CLOCK_S as CLOCK,
 | 
			
		||||
        POWER_S as POWER,
 | 
			
		||||
        RESET_S as RESET,
 | 
			
		||||
        OSCILLATORS_S as OSCILLATORS,
 | 
			
		||||
        REGULATORS_S as REGULATORS,
 | 
			
		||||
        CRACENCORE_S as CRACENCORE,
 | 
			
		||||
        CPUC_S as CPUC,
 | 
			
		||||
        ICACHE_S as ICACHE,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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;
 | 
			
		||||
 | 
			
		||||
//pub const FLASH_SIZE: usize = 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
embassy_hal_internal::peripherals! {
 | 
			
		||||
    // GPIO port 0
 | 
			
		||||
    P0_00,
 | 
			
		||||
    P0_01,
 | 
			
		||||
    P0_02,
 | 
			
		||||
    P0_03,
 | 
			
		||||
    P0_04,
 | 
			
		||||
    P0_05,
 | 
			
		||||
    P0_06,
 | 
			
		||||
 | 
			
		||||
    // 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,
 | 
			
		||||
    P1_16,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // GPIO port 2
 | 
			
		||||
    P2_00,
 | 
			
		||||
    P2_01,
 | 
			
		||||
    P2_02,
 | 
			
		||||
    P2_03,
 | 
			
		||||
    P2_04,
 | 
			
		||||
    P2_05,
 | 
			
		||||
    P2_06,
 | 
			
		||||
    P2_07,
 | 
			
		||||
    P2_08,
 | 
			
		||||
    P2_09,
 | 
			
		||||
    P2_10,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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!(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_pin!(P1_16, 1, 16);
 | 
			
		||||
 | 
			
		||||
impl_pin!(P2_00, 2, 0);
 | 
			
		||||
impl_pin!(P2_01, 2, 1);
 | 
			
		||||
impl_pin!(P2_02, 2, 2);
 | 
			
		||||
impl_pin!(P2_03, 2, 3);
 | 
			
		||||
impl_pin!(P2_04, 2, 4);
 | 
			
		||||
impl_pin!(P2_05, 2, 5);
 | 
			
		||||
impl_pin!(P2_06, 2, 6);
 | 
			
		||||
impl_pin!(P2_07, 2, 7);
 | 
			
		||||
impl_pin!(P2_08, 2, 8);
 | 
			
		||||
impl_pin!(P2_09, 2, 9);
 | 
			
		||||
impl_pin!(P2_10, 2, 10);
 | 
			
		||||
 | 
			
		||||
embassy_hal_internal::interrupt_mod!(
 | 
			
		||||
    SWI00,
 | 
			
		||||
    SWI01,
 | 
			
		||||
    SWI02,
 | 
			
		||||
    SWI03,
 | 
			
		||||
    SPU00,
 | 
			
		||||
    MPC00,
 | 
			
		||||
    AAR00_CCM00,
 | 
			
		||||
    ECB00,
 | 
			
		||||
    CRACEN,
 | 
			
		||||
    SERIAL00,
 | 
			
		||||
    RRAMC,
 | 
			
		||||
    VPR00,
 | 
			
		||||
    CTRLAP,
 | 
			
		||||
    TIMER00,
 | 
			
		||||
    SPU10,
 | 
			
		||||
    TIMER10,
 | 
			
		||||
    RTC10,
 | 
			
		||||
    EGU10,
 | 
			
		||||
    RADIO_0,
 | 
			
		||||
    RADIO_1,
 | 
			
		||||
    SPU20,
 | 
			
		||||
    SERIAL20,
 | 
			
		||||
    SERIAL21,
 | 
			
		||||
    SERIAL22,
 | 
			
		||||
    EGU20,
 | 
			
		||||
    TIMER20,
 | 
			
		||||
    TIMER21,
 | 
			
		||||
    TIMER22,
 | 
			
		||||
    TIMER23,
 | 
			
		||||
    TIMER24,
 | 
			
		||||
    PDM20,
 | 
			
		||||
    PDM21,
 | 
			
		||||
    PWM20,
 | 
			
		||||
    PWM21,
 | 
			
		||||
    PWM22,
 | 
			
		||||
    SAADC,
 | 
			
		||||
    NFCT,
 | 
			
		||||
    TEMP,
 | 
			
		||||
    GPIOTE20_0,
 | 
			
		||||
    GPIOTE20_1,
 | 
			
		||||
    TAMPC,
 | 
			
		||||
    I2S20,
 | 
			
		||||
    QDEC20,
 | 
			
		||||
    QDEC21,
 | 
			
		||||
    GRTC_0,
 | 
			
		||||
    GRTC_1,
 | 
			
		||||
    GRTC_2,
 | 
			
		||||
    GRTC_3,
 | 
			
		||||
    SPU30,
 | 
			
		||||
    SERIAL30,
 | 
			
		||||
    RTC30,
 | 
			
		||||
    COMP_LPCOMP,
 | 
			
		||||
    WDT30,
 | 
			
		||||
    WDT31,
 | 
			
		||||
    GPIOTE30_0,
 | 
			
		||||
    GPIOTE30_1,
 | 
			
		||||
    CLOCK_POWER,
 | 
			
		||||
);
 | 
			
		||||
@ -23,6 +23,10 @@ pub enum Port {
 | 
			
		||||
    /// Port 1, only available on some MCUs.
 | 
			
		||||
    #[cfg(feature = "_gpio-p1")]
 | 
			
		||||
    Port1,
 | 
			
		||||
 | 
			
		||||
    /// Port 2, only available on some MCUs.
 | 
			
		||||
    #[cfg(feature = "_gpio-p2")]
 | 
			
		||||
    Port2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Pull setting for an input.
 | 
			
		||||
@ -99,8 +103,83 @@ impl From<Level> for bool {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Drive strength settings for a given output level.
 | 
			
		||||
// These numbers match vals::Drive exactly so hopefully the compiler will unify them.
 | 
			
		||||
#[cfg(feature = "_nrf54l")]
 | 
			
		||||
#[derive(Clone, Copy, Debug, PartialEq)]
 | 
			
		||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
			
		||||
#[repr(u8)]
 | 
			
		||||
pub enum LevelDrive {
 | 
			
		||||
    /// Disconnect (do not drive the output at all)
 | 
			
		||||
    Disconnect = 2,
 | 
			
		||||
    /// Standard
 | 
			
		||||
    Standard = 0,
 | 
			
		||||
    /// High drive
 | 
			
		||||
    High = 1,
 | 
			
		||||
    /// Extra high drive
 | 
			
		||||
    ExtraHigh = 3,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Drive strength settings for an output pin.
 | 
			
		||||
///
 | 
			
		||||
/// This is a combination of two drive levels, used when the pin is set
 | 
			
		||||
/// low and high respectively.
 | 
			
		||||
#[cfg(feature = "_nrf54l")]
 | 
			
		||||
#[derive(Clone, Copy, Debug, PartialEq)]
 | 
			
		||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
			
		||||
pub struct OutputDrive {
 | 
			
		||||
    low: LevelDrive,
 | 
			
		||||
    high: LevelDrive,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "_nrf54l")]
 | 
			
		||||
#[allow(non_upper_case_globals)]
 | 
			
		||||
impl OutputDrive {
 | 
			
		||||
    /// Standard '0', standard '1'
 | 
			
		||||
    pub const Standard: Self = Self {
 | 
			
		||||
        low: LevelDrive::Standard,
 | 
			
		||||
        high: LevelDrive::Standard,
 | 
			
		||||
    };
 | 
			
		||||
    /// High drive '0', standard '1'
 | 
			
		||||
    pub const HighDrive0Standard1: Self = Self {
 | 
			
		||||
        low: LevelDrive::High,
 | 
			
		||||
        high: LevelDrive::Standard,
 | 
			
		||||
    };
 | 
			
		||||
    /// Standard '0', high drive '1'
 | 
			
		||||
    pub const Standard0HighDrive1: Self = Self {
 | 
			
		||||
        low: LevelDrive::Standard,
 | 
			
		||||
        high: LevelDrive::High,
 | 
			
		||||
    };
 | 
			
		||||
    /// High drive '0', high 'drive '1'
 | 
			
		||||
    pub const HighDrive: Self = Self {
 | 
			
		||||
        low: LevelDrive::High,
 | 
			
		||||
        high: LevelDrive::High,
 | 
			
		||||
    };
 | 
			
		||||
    /// Disconnect '0' standard '1' (normally used for wired-or connections)
 | 
			
		||||
    pub const Disconnect0Standard1: Self = Self {
 | 
			
		||||
        low: LevelDrive::Disconnect,
 | 
			
		||||
        high: LevelDrive::Standard,
 | 
			
		||||
    };
 | 
			
		||||
    /// Disconnect '0', high drive '1' (normally used for wired-or connections)
 | 
			
		||||
    pub const Disconnect0HighDrive1: Self = Self {
 | 
			
		||||
        low: LevelDrive::Disconnect,
 | 
			
		||||
        high: LevelDrive::High,
 | 
			
		||||
    };
 | 
			
		||||
    /// Standard '0'. disconnect '1' (also known as "open drain", normally used for wired-and connections)
 | 
			
		||||
    pub const Standard0Disconnect1: Self = Self {
 | 
			
		||||
        low: LevelDrive::Standard,
 | 
			
		||||
        high: LevelDrive::Disconnect,
 | 
			
		||||
    };
 | 
			
		||||
    /// High drive '0', disconnect '1' (also known as "open drain", normally used for wired-and connections)
 | 
			
		||||
    pub const HighDrive0Disconnect1: Self = Self {
 | 
			
		||||
        low: LevelDrive::High,
 | 
			
		||||
        high: LevelDrive::Disconnect,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Drive strength settings for an output pin.
 | 
			
		||||
// These numbers match vals::Drive exactly so hopefully the compiler will unify them.
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
#[derive(Clone, Copy, Debug, PartialEq)]
 | 
			
		||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
			
		||||
#[repr(u8)]
 | 
			
		||||
@ -185,8 +264,10 @@ impl<'d> Output<'d> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn convert_drive(drive: OutputDrive) -> vals::Drive {
 | 
			
		||||
    match drive {
 | 
			
		||||
pub(crate) fn convert_drive(w: &mut pac::gpio::regs::PinCnf, drive: OutputDrive) {
 | 
			
		||||
    #[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
    {
 | 
			
		||||
        let drive = match drive {
 | 
			
		||||
            OutputDrive::Standard => vals::Drive::S0S1,
 | 
			
		||||
            OutputDrive::HighDrive0Standard1 => vals::Drive::H0S1,
 | 
			
		||||
            OutputDrive::Standard0HighDrive1 => vals::Drive::S0H1,
 | 
			
		||||
@ -195,6 +276,23 @@ pub(crate) fn convert_drive(drive: OutputDrive) -> vals::Drive {
 | 
			
		||||
            OutputDrive::Disconnect0HighDrive1 => vals::Drive::D0H1,
 | 
			
		||||
            OutputDrive::Standard0Disconnect1 => vals::Drive::S0D1,
 | 
			
		||||
            OutputDrive::HighDrive0Disconnect1 => vals::Drive::H0D1,
 | 
			
		||||
        };
 | 
			
		||||
        w.set_drive(drive);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "_nrf54l")]
 | 
			
		||||
    {
 | 
			
		||||
        fn convert(d: LevelDrive) -> vals::Drive {
 | 
			
		||||
            match d {
 | 
			
		||||
                LevelDrive::Disconnect => vals::Drive::D,
 | 
			
		||||
                LevelDrive::Standard => vals::Drive::S,
 | 
			
		||||
                LevelDrive::High => vals::Drive::H,
 | 
			
		||||
                LevelDrive::ExtraHigh => vals::Drive::E,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        w.set_drive0(convert(drive.low));
 | 
			
		||||
        w.set_drive0(convert(drive.high));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -234,7 +332,7 @@ impl<'d> Flex<'d> {
 | 
			
		||||
            w.set_dir(vals::Dir::INPUT);
 | 
			
		||||
            w.set_input(vals::Input::CONNECT);
 | 
			
		||||
            w.set_pull(convert_pull(pull));
 | 
			
		||||
            w.set_drive(vals::Drive::S0S1);
 | 
			
		||||
            convert_drive(w, OutputDrive::Standard);
 | 
			
		||||
            w.set_sense(vals::Sense::DISABLED);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@ -249,9 +347,10 @@ impl<'d> Flex<'d> {
 | 
			
		||||
            w.set_dir(vals::Dir::OUTPUT);
 | 
			
		||||
            w.set_input(vals::Input::DISCONNECT);
 | 
			
		||||
            w.set_pull(vals::Pull::DISABLED);
 | 
			
		||||
            w.set_drive(convert_drive(drive));
 | 
			
		||||
            convert_drive(w, drive);
 | 
			
		||||
            w.set_sense(vals::Sense::DISABLED);
 | 
			
		||||
        });
 | 
			
		||||
        info!("pin_cnf: {:08x}", self.pin.conf().read().0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Put the pin into input + output mode.
 | 
			
		||||
@ -269,7 +368,7 @@ impl<'d> Flex<'d> {
 | 
			
		||||
            w.set_dir(vals::Dir::OUTPUT);
 | 
			
		||||
            w.set_input(vals::Input::CONNECT);
 | 
			
		||||
            w.set_pull(convert_pull(pull));
 | 
			
		||||
            w.set_drive(convert_drive(drive));
 | 
			
		||||
            convert_drive(w, drive);
 | 
			
		||||
            w.set_sense(vals::Sense::DISABLED);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@ -377,6 +476,8 @@ pub(crate) trait SealedPin {
 | 
			
		||||
            0 => pac::P0,
 | 
			
		||||
            #[cfg(feature = "_gpio-p1")]
 | 
			
		||||
            1 => pac::P1,
 | 
			
		||||
            #[cfg(feature = "_gpio-p2")]
 | 
			
		||||
            2 => pac::P2,
 | 
			
		||||
            _ => unsafe { unreachable_unchecked() },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -415,6 +516,8 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static
 | 
			
		||||
            0 => Port::Port0,
 | 
			
		||||
            #[cfg(feature = "_gpio-p1")]
 | 
			
		||||
            1 => Port::Port1,
 | 
			
		||||
            #[cfg(feature = "_gpio-p2")]
 | 
			
		||||
            2 => Port::Port2,
 | 
			
		||||
            _ => unsafe { unreachable_unchecked() },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -463,6 +566,7 @@ impl SealedPin for AnyPin {
 | 
			
		||||
// ====================
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
#[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO
 | 
			
		||||
pub(crate) trait PselBits {
 | 
			
		||||
    fn psel_bits(&self) -> pac::shared::regs::Psel;
 | 
			
		||||
}
 | 
			
		||||
@ -479,6 +583,7 @@ impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
#[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO
 | 
			
		||||
pub(crate) const DISCONNECTED: Psel = Psel(1 << 31);
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,8 @@
 | 
			
		||||
    feature = "nrf5340-app-s",
 | 
			
		||||
    feature = "nrf5340-app-ns",
 | 
			
		||||
    feature = "nrf5340-net",
 | 
			
		||||
    feature = "nrf54l15-app-s",
 | 
			
		||||
    feature = "nrf54l15-app-ns",
 | 
			
		||||
    feature = "nrf9160-s",
 | 
			
		||||
    feature = "nrf9160-ns",
 | 
			
		||||
    feature = "nrf9120-s",
 | 
			
		||||
@ -44,6 +46,8 @@ compile_error!(
 | 
			
		||||
    nrf5340-app-s,
 | 
			
		||||
    nrf5340-app-ns,
 | 
			
		||||
    nrf5340-net,
 | 
			
		||||
    nrf54l15-app-s,
 | 
			
		||||
    nrf54l15-app-ns,
 | 
			
		||||
    nrf9160-s,
 | 
			
		||||
    nrf9160-ns,
 | 
			
		||||
    nrf9120-s,
 | 
			
		||||
@ -68,21 +72,22 @@ pub(crate) mod util;
 | 
			
		||||
#[cfg(feature = "_time-driver")]
 | 
			
		||||
mod time_driver;
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod buffered_uarte;
 | 
			
		||||
pub mod gpio;
 | 
			
		||||
#[cfg(feature = "gpiote")]
 | 
			
		||||
pub mod gpiote;
 | 
			
		||||
 | 
			
		||||
// TODO: tested on other chips
 | 
			
		||||
#[cfg(not(any(feature = "_nrf91", feature = "_nrf5340-app")))]
 | 
			
		||||
pub mod radio;
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod egu;
 | 
			
		||||
pub mod gpio;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(feature = "gpiote")]
 | 
			
		||||
pub mod gpiote;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
 | 
			
		||||
pub mod i2s;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
pub mod nvmc;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(any(
 | 
			
		||||
    feature = "nrf52810",
 | 
			
		||||
    feature = "nrf52811",
 | 
			
		||||
@ -93,7 +98,9 @@ pub mod nvmc;
 | 
			
		||||
    feature = "_nrf91",
 | 
			
		||||
))]
 | 
			
		||||
pub mod pdm;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
pub mod ppi;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(
 | 
			
		||||
    feature = "_nrf51",
 | 
			
		||||
    feature = "nrf52805",
 | 
			
		||||
@ -101,27 +108,42 @@ pub mod ppi;
 | 
			
		||||
    feature = "_nrf5340-net"
 | 
			
		||||
)))]
 | 
			
		||||
pub mod pwm;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(feature = "_nrf51", feature = "_nrf91", feature = "_nrf5340-net")))]
 | 
			
		||||
pub mod qdec;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))]
 | 
			
		||||
pub mod qspi;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(feature = "_nrf91", feature = "_nrf5340-app")))]
 | 
			
		||||
pub mod radio;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))]
 | 
			
		||||
pub mod rng;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))]
 | 
			
		||||
pub mod saadc;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod spim;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod spis;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
pub mod temp;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
pub mod timer;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod twim;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod twis;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
pub mod uarte;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(any(
 | 
			
		||||
    feature = "_nrf5340-app",
 | 
			
		||||
    feature = "nrf52820",
 | 
			
		||||
@ -129,6 +151,7 @@ pub mod uarte;
 | 
			
		||||
    feature = "nrf52840"
 | 
			
		||||
))]
 | 
			
		||||
pub mod usb;
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
#[cfg(not(feature = "_nrf5340"))]
 | 
			
		||||
pub mod wdt;
 | 
			
		||||
 | 
			
		||||
@ -143,6 +166,7 @@ pub mod wdt;
 | 
			
		||||
#[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 = "_nrf54l15-app", path = "chips/nrf54l15_app.rs")]
 | 
			
		||||
#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
 | 
			
		||||
#[cfg_attr(feature = "_nrf9120", path = "chips/nrf9120.rs")]
 | 
			
		||||
mod chip;
 | 
			
		||||
@ -249,10 +273,10 @@ pub mod config {
 | 
			
		||||
        /// External source from xtal.
 | 
			
		||||
        ExternalXtal,
 | 
			
		||||
        /// External source from xtal with low swing applied.
 | 
			
		||||
        #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
        #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
 | 
			
		||||
        ExternalLowSwing,
 | 
			
		||||
        /// External source from xtal with full swing applied.
 | 
			
		||||
        #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
        #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
 | 
			
		||||
        ExternalFullSwing,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -325,7 +349,7 @@ pub mod config {
 | 
			
		||||
        pub hfclk_source: HfclkSource,
 | 
			
		||||
        /// Low frequency clock source.
 | 
			
		||||
        pub lfclk_source: LfclkSource,
 | 
			
		||||
        #[cfg(not(feature = "_nrf5340-net"))]
 | 
			
		||||
        #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
 | 
			
		||||
        /// DCDC configuration.
 | 
			
		||||
        pub dcdc: DcdcConfig,
 | 
			
		||||
        /// GPIOTE interrupt priority. Should be lower priority than softdevice if used.
 | 
			
		||||
@ -346,7 +370,7 @@ pub mod config {
 | 
			
		||||
                // xtals if they know they have them.
 | 
			
		||||
                hfclk_source: HfclkSource::Internal,
 | 
			
		||||
                lfclk_source: LfclkSource::InternalRC,
 | 
			
		||||
                #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
                #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
 | 
			
		||||
                dcdc: DcdcConfig {
 | 
			
		||||
                    #[cfg(feature = "nrf52840")]
 | 
			
		||||
                    reg0: false,
 | 
			
		||||
@ -415,7 +439,7 @@ mod consts {
 | 
			
		||||
    pub const APPROTECT_DISABLED: u32 = 0x0000_005a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
 | 
			
		||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
 | 
			
		||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 | 
			
		||||
enum WriteResult {
 | 
			
		||||
@ -427,12 +451,12 @@ enum WriteResult {
 | 
			
		||||
    Failed,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
 | 
			
		||||
unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult {
 | 
			
		||||
    uicr_write_masked(address, value, 0xFFFF_FFFF)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
 | 
			
		||||
unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult {
 | 
			
		||||
    let curr_val = address.read_volatile();
 | 
			
		||||
    if curr_val & mask == value & mask {
 | 
			
		||||
@ -469,6 +493,7 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
			
		||||
    let mut needs_reset = false;
 | 
			
		||||
 | 
			
		||||
    // Setup debug protection.
 | 
			
		||||
    #[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
    #[cfg(not(feature = "_nrf51"))]
 | 
			
		||||
    match config.debug {
 | 
			
		||||
        config::Debug::Allowed => {
 | 
			
		||||
@ -592,15 +617,25 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
			
		||||
    match config.hfclk_source {
 | 
			
		||||
        config::HfclkSource::Internal => {}
 | 
			
		||||
        config::HfclkSource::ExternalXtal => {
 | 
			
		||||
            #[cfg(feature = "_nrf54l")]
 | 
			
		||||
            {
 | 
			
		||||
                r.events_xostarted().write_value(0);
 | 
			
		||||
                r.tasks_xostart().write_value(1);
 | 
			
		||||
                while r.events_xostarted().read() == 0 {}
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
            {
 | 
			
		||||
                // Datasheet says this is likely to take 0.36ms
 | 
			
		||||
                r.events_hfclkstarted().write_value(0);
 | 
			
		||||
                r.tasks_hfclkstart().write_value(1);
 | 
			
		||||
                while r.events_hfclkstarted().read() == 0 {}
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure LFCLK.
 | 
			
		||||
    #[cfg(not(any(feature = "_nrf51", feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
    #[cfg(not(any(feature = "_nrf51", feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
 | 
			
		||||
    match config.lfclk_source {
 | 
			
		||||
        config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::RC)),
 | 
			
		||||
        config::LfclkSource::Synthesized => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::SYNTH)),
 | 
			
		||||
@ -621,6 +656,12 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
			
		||||
        config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
 | 
			
		||||
        config::LfclkSource::ExternalXtal => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO)),
 | 
			
		||||
    }
 | 
			
		||||
    #[cfg(feature = "_nrf54l")]
 | 
			
		||||
    match config.lfclk_source {
 | 
			
		||||
        config::LfclkSource::InternalRC => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
 | 
			
		||||
        config::LfclkSource::Synthesized => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFSYNT)),
 | 
			
		||||
        config::LfclkSource::ExternalXtal => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO)),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Start LFCLK.
 | 
			
		||||
    // Datasheet says this could take 100us from synth source
 | 
			
		||||
@ -629,7 +670,7 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
			
		||||
    r.tasks_lfclkstart().write_value(1);
 | 
			
		||||
    while r.events_lfclkstarted().read() == 0 {}
 | 
			
		||||
 | 
			
		||||
    #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
 | 
			
		||||
    #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
 | 
			
		||||
    {
 | 
			
		||||
        // Setup DCDCs.
 | 
			
		||||
        #[cfg(feature = "nrf52840")]
 | 
			
		||||
@ -663,6 +704,7 @@ pub fn init(config: config::Config) -> Peripherals {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Init GPIOTE
 | 
			
		||||
    #[cfg(not(feature = "_nrf54l"))] // TODO
 | 
			
		||||
    #[cfg(feature = "gpiote")]
 | 
			
		||||
    gpiote::init(config.gpiote_interrupt_priority);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -133,7 +133,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
 | 
			
		||||
            pin.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_input(gpiovals::Input::DISCONNECT);
 | 
			
		||||
                w.set_drive(convert_drive(config.ch0_drive));
 | 
			
		||||
                convert_drive(w, config.ch0_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(pin) = &ch1 {
 | 
			
		||||
@ -141,7 +141,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
 | 
			
		||||
            pin.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_input(gpiovals::Input::DISCONNECT);
 | 
			
		||||
                w.set_drive(convert_drive(config.ch1_drive));
 | 
			
		||||
                convert_drive(w, config.ch1_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(pin) = &ch2 {
 | 
			
		||||
@ -149,7 +149,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
 | 
			
		||||
            pin.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_input(gpiovals::Input::DISCONNECT);
 | 
			
		||||
                w.set_drive(convert_drive(config.ch2_drive));
 | 
			
		||||
                convert_drive(w, config.ch2_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(pin) = &ch3 {
 | 
			
		||||
@ -157,7 +157,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
 | 
			
		||||
            pin.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_input(gpiovals::Input::DISCONNECT);
 | 
			
		||||
                w.set_drive(convert_drive(config.ch3_drive));
 | 
			
		||||
                convert_drive(w, config.ch3_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -832,7 +832,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
 | 
			
		||||
    #[inline(always)]
 | 
			
		||||
    pub fn set_ch0_drive(&self, drive: OutputDrive) {
 | 
			
		||||
        if let Some(pin) = &self.ch0 {
 | 
			
		||||
            pin.conf().modify(|w| w.set_drive(convert_drive(drive)));
 | 
			
		||||
            pin.conf().modify(|w| convert_drive(w, drive));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -840,7 +840,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
 | 
			
		||||
    #[inline(always)]
 | 
			
		||||
    pub fn set_ch1_drive(&self, drive: OutputDrive) {
 | 
			
		||||
        if let Some(pin) = &self.ch1 {
 | 
			
		||||
            pin.conf().modify(|w| w.set_drive(convert_drive(drive)));
 | 
			
		||||
            pin.conf().modify(|w| convert_drive(w, drive));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -848,7 +848,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
 | 
			
		||||
    #[inline(always)]
 | 
			
		||||
    pub fn set_ch2_drive(&self, drive: OutputDrive) {
 | 
			
		||||
        if let Some(pin) = &self.ch2 {
 | 
			
		||||
            pin.conf().modify(|w| w.set_drive(convert_drive(drive)));
 | 
			
		||||
            pin.conf().modify(|w| convert_drive(w, drive));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -856,7 +856,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
 | 
			
		||||
    #[inline(always)]
 | 
			
		||||
    pub fn set_ch3_drive(&self, drive: OutputDrive) {
 | 
			
		||||
        if let Some(pin) = &self.ch3 {
 | 
			
		||||
            pin.conf().modify(|w| w.set_drive(convert_drive(drive)));
 | 
			
		||||
            pin.conf().modify(|w| convert_drive(w, drive));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -173,13 +173,13 @@ impl<'d, T: Instance> Spim<'d, T> {
 | 
			
		||||
        if let Some(sck) = &sck {
 | 
			
		||||
            sck.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_drive(convert_drive(config.sck_drive))
 | 
			
		||||
                convert_drive(w, config.sck_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(mosi) = &mosi {
 | 
			
		||||
            mosi.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_drive(convert_drive(config.mosi_drive))
 | 
			
		||||
                convert_drive(w, config.mosi_drive);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if let Some(miso) = &miso {
 | 
			
		||||
 | 
			
		||||
@ -203,7 +203,7 @@ impl<'d, T: Instance> Spis<'d, T> {
 | 
			
		||||
        if let Some(miso) = &miso {
 | 
			
		||||
            miso.conf().write(|w| {
 | 
			
		||||
                w.set_dir(gpiovals::Dir::OUTPUT);
 | 
			
		||||
                w.set_drive(convert_drive(config.miso_drive))
 | 
			
		||||
                convert_drive(w, config.miso_drive);
 | 
			
		||||
            });
 | 
			
		||||
            r.psel().miso().write_value(miso.psel_bits());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,11 @@ use embassy_time_driver::{AlarmHandle, Driver};
 | 
			
		||||
use crate::interrupt::InterruptExt;
 | 
			
		||||
use crate::{interrupt, pac};
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "_nrf54l")]
 | 
			
		||||
fn rtc() -> pac::rtc::Rtc {
 | 
			
		||||
    pac::RTC30
 | 
			
		||||
}
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
fn rtc() -> pac::rtc::Rtc {
 | 
			
		||||
    pac::RTC1
 | 
			
		||||
}
 | 
			
		||||
@ -141,9 +146,17 @@ impl RtcDriver {
 | 
			
		||||
        // Wait for clear
 | 
			
		||||
        while r.counter().read().0 != 0 {}
 | 
			
		||||
 | 
			
		||||
        #[cfg(feature = "_nrf54l")]
 | 
			
		||||
        {
 | 
			
		||||
            interrupt::RTC30.set_priority(irq_prio);
 | 
			
		||||
            unsafe { interrupt::RTC30.enable() };
 | 
			
		||||
        }
 | 
			
		||||
        #[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
        {
 | 
			
		||||
            interrupt::RTC1.set_priority(irq_prio);
 | 
			
		||||
            unsafe { interrupt::RTC1.enable() };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn on_interrupt(&self) {
 | 
			
		||||
        let r = rtc();
 | 
			
		||||
@ -292,6 +305,14 @@ impl Driver for RtcDriver {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "_nrf54l")]
 | 
			
		||||
#[cfg(feature = "rt")]
 | 
			
		||||
#[interrupt]
 | 
			
		||||
fn RTC30() {
 | 
			
		||||
    DRIVER.on_interrupt()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "_nrf54l"))]
 | 
			
		||||
#[cfg(feature = "rt")]
 | 
			
		||||
#[interrupt]
 | 
			
		||||
fn RTC1() {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								examples/nrf54l15/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								examples/nrf54l15/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
 | 
			
		||||
# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list`
 | 
			
		||||
runner = "../../sshprobe.sh"
 | 
			
		||||
 | 
			
		||||
[build]
 | 
			
		||||
target = "thumbv8m.main-none-eabihf"
 | 
			
		||||
 | 
			
		||||
[env]
 | 
			
		||||
DEFMT_LOG = "trace"
 | 
			
		||||
							
								
								
									
										20
									
								
								examples/nrf54l15/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								examples/nrf54l15/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
[package]
 | 
			
		||||
edition = "2021"
 | 
			
		||||
name = "embassy-nrf54l15-examples"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
license = "MIT OR Apache-2.0"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embassy-executor = { version = "0.6.3", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
 | 
			
		||||
embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 | 
			
		||||
embassy-nrf = { version = "0.2.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
 | 
			
		||||
 | 
			
		||||
defmt = "0.3"
 | 
			
		||||
defmt-rtt = "0.4"
 | 
			
		||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
 | 
			
		||||
 | 
			
		||||
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
 | 
			
		||||
[profile.release]
 | 
			
		||||
debug = 2
 | 
			
		||||
							
								
								
									
										35
									
								
								examples/nrf54l15/build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								examples/nrf54l15/build.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
//! This build script copies the `memory.x` file from the crate root into
 | 
			
		||||
//! a directory where the linker can always find it at build time.
 | 
			
		||||
//! For many projects this is optional, as the linker always searches the
 | 
			
		||||
//! project root directory -- wherever `Cargo.toml` is. However, if you
 | 
			
		||||
//! are using a workspace or have a more complicated build setup, this
 | 
			
		||||
//! build script becomes required. Additionally, by requesting that
 | 
			
		||||
//! Cargo re-run the build script whenever `memory.x` is changed,
 | 
			
		||||
//! updating `memory.x` ensures a rebuild of the application with the
 | 
			
		||||
//! new memory settings.
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    // Put `memory.x` in our output directory and ensure it's
 | 
			
		||||
    // on the linker search path.
 | 
			
		||||
    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
 | 
			
		||||
    File::create(out.join("memory.x"))
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .write_all(include_bytes!("memory.x"))
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    println!("cargo:rustc-link-search={}", out.display());
 | 
			
		||||
 | 
			
		||||
    // By default, Cargo will re-run a build script whenever
 | 
			
		||||
    // any file in the project changes. By specifying `memory.x`
 | 
			
		||||
    // here, we ensure the build script is only re-run when
 | 
			
		||||
    // `memory.x` is changed.
 | 
			
		||||
    println!("cargo:rerun-if-changed=memory.x");
 | 
			
		||||
 | 
			
		||||
    println!("cargo:rustc-link-arg-bins=--nmagic");
 | 
			
		||||
    println!("cargo:rustc-link-arg-bins=-Tlink.x");
 | 
			
		||||
    println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								examples/nrf54l15/memory.x
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								examples/nrf54l15/memory.x
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
MEMORY
 | 
			
		||||
{
 | 
			
		||||
  FLASH : ORIGIN = 0x00000000, LENGTH = 1536K
 | 
			
		||||
  RAM : ORIGIN = 0x20000000, LENGTH = 256K
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								examples/nrf54l15/src/bin/blinky.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								examples/nrf54l15/src/bin/blinky.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
#![no_std]
 | 
			
		||||
#![no_main]
 | 
			
		||||
 | 
			
		||||
use defmt::info;
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
 | 
			
		||||
use embassy_time::Timer;
 | 
			
		||||
use {defmt_rtt as _, panic_probe as _};
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::main]
 | 
			
		||||
async fn main(_spawner: Spawner) {
 | 
			
		||||
    let p = embassy_nrf::init(Default::default());
 | 
			
		||||
    let mut led = Output::new(p.P2_09, Level::Low, OutputDrive::Standard);
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        info!("high!");
 | 
			
		||||
        led.set_high();
 | 
			
		||||
        Timer::after_millis(300).await;
 | 
			
		||||
        info!("low!");
 | 
			
		||||
        led.set_low();
 | 
			
		||||
        Timer::after_millis(300).await;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user