mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 14:22:33 +00:00
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,16 +264,35 @@ impl<'d> Output<'d> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn convert_drive(drive: OutputDrive) -> vals::Drive {
|
||||
match drive {
|
||||
OutputDrive::Standard => vals::Drive::S0S1,
|
||||
OutputDrive::HighDrive0Standard1 => vals::Drive::H0S1,
|
||||
OutputDrive::Standard0HighDrive1 => vals::Drive::S0H1,
|
||||
OutputDrive::HighDrive => vals::Drive::H0H1,
|
||||
OutputDrive::Disconnect0Standard1 => vals::Drive::D0S1,
|
||||
OutputDrive::Disconnect0HighDrive1 => vals::Drive::D0H1,
|
||||
OutputDrive::Standard0Disconnect1 => vals::Drive::S0D1,
|
||||
OutputDrive::HighDrive0Disconnect1 => vals::Drive::H0D1,
|
||||
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,
|
||||
OutputDrive::HighDrive => vals::Drive::H0H1,
|
||||
OutputDrive::Disconnect0Standard1 => vals::Drive::D0S1,
|
||||
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 => {
|
||||
// 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 {}
|
||||
#[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,8 +146,16 @@ impl RtcDriver {
|
||||
// Wait for clear
|
||||
while r.counter().read().0 != 0 {}
|
||||
|
||||
interrupt::RTC1.set_priority(irq_prio);
|
||||
unsafe { interrupt::RTC1.enable() };
|
||||
#[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) {
|
||||
@ -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…
Reference in New Issue
Block a user