1170: nrf: add support for UICR configuration. r=Dirbaio a=Dirbaio

- APPROTECT enable/disable. Notably this fixes issues with nrf52-rev3 and nrf53 from locking itself at reset.
- Use NFC pins as GPIO.
- Use RESET pin as GPIO.

NFC and RESET pins singletons are made available only when usable as GPIO, for compile-time checking.

TODO: test
- [x] nrf52 rev1
- [x] nrf52 rev3
- [x] nrf53
- [x] nrf91

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2023-02-20 00:47:15 +00:00 committed by GitHub
commit b05cd77a62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 284 additions and 19 deletions

4
ci.sh
View File

@ -46,8 +46,8 @@ cargo batch \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52820,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52820,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52832,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52832,gpiote,time-driver-rtc1,reset-pin-as-gpio \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52833,gpiote,time-driver-rtc1,unstable-traits \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52833,gpiote,time-driver-rtc1,unstable-traits,nfc-pins-as-gpio \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-s,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-s,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-ns,gpiote,time-driver-rtc1,unstable-traits \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-ns,gpiote,time-driver-rtc1,unstable-traits \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-s,gpiote,time-driver-rtc1,unstable-traits \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-s,gpiote,time-driver-rtc1,unstable-traits \

View File

@ -34,22 +34,30 @@ unstable-pac = []
# Implement embedded-hal-async traits if `nightly` is set as well. # Implement embedded-hal-async traits if `nightly` is set as well.
unstable-traits = ["embedded-hal-1"] unstable-traits = ["embedded-hal-1"]
nrf52805 = ["nrf52805-pac", "_ppi"] nrf52805 = ["nrf52805-pac", "_nrf52"]
nrf52810 = ["nrf52810-pac", "_ppi"] nrf52810 = ["nrf52810-pac", "_nrf52"]
nrf52811 = ["nrf52811-pac", "_ppi"] nrf52811 = ["nrf52811-pac", "_nrf52"]
nrf52820 = ["nrf52820-pac", "_ppi"] nrf52820 = ["nrf52820-pac", "_nrf52"]
nrf52832 = ["nrf52832-pac", "_ppi"] nrf52832 = ["nrf52832-pac", "_nrf52"]
nrf52833 = ["nrf52833-pac", "_ppi", "_gpio-p1"] nrf52833 = ["nrf52833-pac", "_nrf52", "_gpio-p1"]
nrf52840 = ["nrf52840-pac", "_ppi", "_gpio-p1"] nrf52840 = ["nrf52840-pac", "_nrf52", "_gpio-p1"]
nrf5340-app-s = ["_nrf5340-app"] nrf5340-app-s = ["_nrf5340-app", "_s"]
nrf5340-app-ns = ["_nrf5340-app"] nrf5340-app-ns = ["_nrf5340-app", "_ns"]
nrf5340-net = ["_nrf5340-net"] nrf5340-net = ["_nrf5340-net"]
nrf9160-s = ["_nrf9160"] nrf9160-s = ["_nrf9160", "_s"]
nrf9160-ns = ["_nrf9160"] nrf9160-ns = ["_nrf9160", "_ns"]
gpiote = [] gpiote = []
time-driver-rtc1 = ["_time-driver"] time-driver-rtc1 = ["_time-driver"]
# Allow using the NFC pins as regular GPIO pins (P0_09/P0_10 on nRF52, P0_02/P0_03 on nRF53)
nfc-pins-as-gpio = []
# Allow using the RST pin as a regular GPIO pin.
# nrf52805, nrf52810, nrf52811, nrf52832: P0_21
# nrf52820, nrf52833, nrf52840: P0_18
reset-pin-as-gpio = []
# Features starting with `_` are for internal use only. They're not intended # Features starting with `_` are for internal use only. They're not intended
# to be enabled by other crates, and are not covered by semver guarantees. # to be enabled by other crates, and are not covered by semver guarantees.
@ -57,9 +65,14 @@ _nrf5340-app = ["_nrf5340", "nrf5340-app-pac"]
_nrf5340-net = ["_nrf5340", "nrf5340-net-pac"] _nrf5340-net = ["_nrf5340", "nrf5340-net-pac"]
_nrf5340 = ["_gpio-p1", "_dppi"] _nrf5340 = ["_gpio-p1", "_dppi"]
_nrf9160 = ["nrf9160-pac", "_dppi"] _nrf9160 = ["nrf9160-pac", "_dppi"]
_nrf52 = ["_ppi"]
_time-driver = ["dep:embassy-time", "embassy-time?/tick-hz-32_768"] _time-driver = ["dep:embassy-time", "embassy-time?/tick-hz-32_768"]
# trustzone state.
_s = []
_ns = []
_ppi = [] _ppi = []
_dppi = [] _dppi = []
_gpio-p1 = [] _gpio-p1 = []

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
pub const FLASH_SIZE: usize = 192 * 1024; pub const FLASH_SIZE: usize = 192 * 1024;
pub const RESET_PIN: u32 = 21;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// RTC // RTC
RTC0, RTC0,
@ -108,6 +110,7 @@ embassy_hal_common::peripherals! {
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
#[cfg(feature="reset-pin-as-gpio")]
P0_21, P0_21,
P0_22, P0_22,
P0_23, P0_23,
@ -162,6 +165,7 @@ impl_pin!(P0_17, 0, 17);
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_21, 0, 21); impl_pin!(P0_21, 0, 21);
impl_pin!(P0_22, 0, 22); impl_pin!(P0_22, 0, 22);
impl_pin!(P0_23, 0, 23); impl_pin!(P0_23, 0, 23);

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
pub const FLASH_SIZE: usize = 192 * 1024; pub const FLASH_SIZE: usize = 192 * 1024;
pub const RESET_PIN: u32 = 21;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// RTC // RTC
RTC0, RTC0,
@ -111,6 +113,7 @@ embassy_hal_common::peripherals! {
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
#[cfg(feature="reset-pin-as-gpio")]
P0_21, P0_21,
P0_22, P0_22,
P0_23, P0_23,
@ -170,6 +173,7 @@ impl_pin!(P0_17, 0, 17);
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_21, 0, 21); impl_pin!(P0_21, 0, 21);
impl_pin!(P0_22, 0, 22); impl_pin!(P0_22, 0, 22);
impl_pin!(P0_23, 0, 23); impl_pin!(P0_23, 0, 23);

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
pub const FLASH_SIZE: usize = 192 * 1024; pub const FLASH_SIZE: usize = 192 * 1024;
pub const RESET_PIN: u32 = 21;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// RTC // RTC
RTC0, RTC0,
@ -111,6 +113,7 @@ embassy_hal_common::peripherals! {
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
#[cfg(feature="reset-pin-as-gpio")]
P0_21, P0_21,
P0_22, P0_22,
P0_23, P0_23,
@ -172,6 +175,7 @@ impl_pin!(P0_17, 0, 17);
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_21, 0, 21); impl_pin!(P0_21, 0, 21);
impl_pin!(P0_22, 0, 22); impl_pin!(P0_22, 0, 22);
impl_pin!(P0_23, 0, 23); impl_pin!(P0_23, 0, 23);

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
pub const FLASH_SIZE: usize = 256 * 1024; pub const FLASH_SIZE: usize = 256 * 1024;
pub const RESET_PIN: u32 = 18;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// USB // USB
USBD, USBD,
@ -106,6 +108,7 @@ embassy_hal_common::peripherals! {
P0_15, P0_15,
P0_16, P0_16,
P0_17, P0_17,
#[cfg(feature="reset-pin-as-gpio")]
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
@ -168,6 +171,7 @@ impl_pin!(P0_14, 0, 14);
impl_pin!(P0_15, 0, 15); impl_pin!(P0_15, 0, 15);
impl_pin!(P0_16, 0, 16); impl_pin!(P0_16, 0, 16);
impl_pin!(P0_17, 0, 17); impl_pin!(P0_17, 0, 17);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);

View File

@ -10,6 +10,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 255;
// nrf52832xxAB = 256kb // nrf52832xxAB = 256kb
pub const FLASH_SIZE: usize = 512 * 1024; pub const FLASH_SIZE: usize = 512 * 1024;
pub const RESET_PIN: u32 = 21;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// RTC // RTC
RTC0, RTC0,
@ -109,7 +111,9 @@ embassy_hal_common::peripherals! {
P0_06, P0_06,
P0_07, P0_07,
P0_08, P0_08,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_09, P0_09,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_10, P0_10,
P0_11, P0_11,
P0_12, P0_12,
@ -121,6 +125,7 @@ embassy_hal_common::peripherals! {
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
#[cfg(feature="reset-pin-as-gpio")]
P0_21, P0_21,
P0_22, P0_22,
P0_23, P0_23,
@ -178,7 +183,9 @@ impl_pin!(P0_05, 0, 5);
impl_pin!(P0_06, 0, 6); impl_pin!(P0_06, 0, 6);
impl_pin!(P0_07, 0, 7); impl_pin!(P0_07, 0, 7);
impl_pin!(P0_08, 0, 8); impl_pin!(P0_08, 0, 8);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_09, 0, 9); impl_pin!(P0_09, 0, 9);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_10, 0, 10); impl_pin!(P0_10, 0, 10);
impl_pin!(P0_11, 0, 11); impl_pin!(P0_11, 0, 11);
impl_pin!(P0_12, 0, 12); impl_pin!(P0_12, 0, 12);
@ -190,6 +197,7 @@ impl_pin!(P0_17, 0, 17);
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_21, 0, 21); impl_pin!(P0_21, 0, 21);
impl_pin!(P0_22, 0, 22); impl_pin!(P0_22, 0, 22);
impl_pin!(P0_23, 0, 23); impl_pin!(P0_23, 0, 23);

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
pub const FLASH_SIZE: usize = 512 * 1024; pub const FLASH_SIZE: usize = 512 * 1024;
pub const RESET_PIN: u32 = 18;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// USB // USB
USBD, USBD,
@ -111,7 +113,9 @@ embassy_hal_common::peripherals! {
P0_06, P0_06,
P0_07, P0_07,
P0_08, P0_08,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_09, P0_09,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_10, P0_10,
P0_11, P0_11,
P0_12, P0_12,
@ -120,6 +124,7 @@ embassy_hal_common::peripherals! {
P0_15, P0_15,
P0_16, P0_16,
P0_17, P0_17,
#[cfg(feature="reset-pin-as-gpio")]
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
@ -207,7 +212,9 @@ impl_pin!(P0_05, 0, 5);
impl_pin!(P0_06, 0, 6); impl_pin!(P0_06, 0, 6);
impl_pin!(P0_07, 0, 7); impl_pin!(P0_07, 0, 7);
impl_pin!(P0_08, 0, 8); impl_pin!(P0_08, 0, 8);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_09, 0, 9); impl_pin!(P0_09, 0, 9);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_10, 0, 10); impl_pin!(P0_10, 0, 10);
impl_pin!(P0_11, 0, 11); impl_pin!(P0_11, 0, 11);
impl_pin!(P0_12, 0, 12); impl_pin!(P0_12, 0, 12);
@ -216,6 +223,7 @@ impl_pin!(P0_14, 0, 14);
impl_pin!(P0_15, 0, 15); impl_pin!(P0_15, 0, 15);
impl_pin!(P0_16, 0, 16); impl_pin!(P0_16, 0, 16);
impl_pin!(P0_17, 0, 17); impl_pin!(P0_17, 0, 17);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);

View File

@ -6,6 +6,8 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
pub const FLASH_SIZE: usize = 1024 * 1024; pub const FLASH_SIZE: usize = 1024 * 1024;
pub const RESET_PIN: u32 = 18;
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
// USB // USB
USBD, USBD,
@ -117,7 +119,9 @@ embassy_hal_common::peripherals! {
P0_06, P0_06,
P0_07, P0_07,
P0_08, P0_08,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_09, P0_09,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_10, P0_10,
P0_11, P0_11,
P0_12, P0_12,
@ -126,6 +130,7 @@ embassy_hal_common::peripherals! {
P0_15, P0_15,
P0_16, P0_16,
P0_17, P0_17,
#[cfg(feature="reset-pin-as-gpio")]
P0_18, P0_18,
P0_19, P0_19,
P0_20, P0_20,
@ -212,7 +217,9 @@ impl_pin!(P0_05, 0, 5);
impl_pin!(P0_06, 0, 6); impl_pin!(P0_06, 0, 6);
impl_pin!(P0_07, 0, 7); impl_pin!(P0_07, 0, 7);
impl_pin!(P0_08, 0, 8); impl_pin!(P0_08, 0, 8);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_09, 0, 9); impl_pin!(P0_09, 0, 9);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_10, 0, 10); impl_pin!(P0_10, 0, 10);
impl_pin!(P0_11, 0, 11); impl_pin!(P0_11, 0, 11);
impl_pin!(P0_12, 0, 12); impl_pin!(P0_12, 0, 12);
@ -221,6 +228,7 @@ impl_pin!(P0_14, 0, 14);
impl_pin!(P0_15, 0, 15); impl_pin!(P0_15, 0, 15);
impl_pin!(P0_16, 0, 16); impl_pin!(P0_16, 0, 16);
impl_pin!(P0_17, 0, 17); impl_pin!(P0_17, 0, 17);
#[cfg(feature = "reset-pin-as-gpio")]
impl_pin!(P0_18, 0, 18); impl_pin!(P0_18, 0, 18);
impl_pin!(P0_19, 0, 19); impl_pin!(P0_19, 0, 19);
impl_pin!(P0_20, 0, 20); impl_pin!(P0_20, 0, 20);

View File

@ -304,7 +304,9 @@ embassy_hal_common::peripherals! {
// GPIO port 0 // GPIO port 0
P0_00, P0_00,
P0_01, P0_01,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_02, P0_02,
#[cfg(feature = "nfc-pins-as-gpio")]
P0_03, P0_03,
P0_04, P0_04,
P0_05, P0_05,
@ -393,7 +395,9 @@ impl_timer!(TIMER2, TIMER2, TIMER2);
impl_pin!(P0_00, 0, 0); impl_pin!(P0_00, 0, 0);
impl_pin!(P0_01, 0, 1); impl_pin!(P0_01, 0, 1);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_02, 0, 2); impl_pin!(P0_02, 0, 2);
#[cfg(feature = "nfc-pins-as-gpio")]
impl_pin!(P0_03, 0, 3); impl_pin!(P0_03, 0, 3);
impl_pin!(P0_04, 0, 4); impl_pin!(P0_04, 0, 4);
impl_pin!(P0_05, 0, 5); impl_pin!(P0_05, 0, 5);

View File

@ -24,6 +24,12 @@
)))] )))]
compile_error!("No chip feature activated. You must activate exactly one of the following features: nrf52810, nrf52811, nrf52832, nrf52833, nrf52840"); compile_error!("No chip feature activated. You must activate exactly one of the following features: nrf52810, nrf52811, nrf52832, nrf52833, nrf52840");
#[cfg(all(feature = "reset-pin-as-gpio", not(feature = "_nrf52")))]
compile_error!("feature `reset-pin-as-gpio` is only valid for nRF52 series chips.");
#[cfg(all(feature = "nfc-pins-as-gpio", not(any(feature = "_nrf52", feature = "_nrf5340-app"))))]
compile_error!("feature `nfc-pins-as-gpio` is only valid for nRF52, or nRF53's application core.");
// This mod MUST go first, so that the others see its macros. // This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt; pub(crate) mod fmt;
pub(crate) mod util; pub(crate) mod util;
@ -139,6 +145,19 @@ pub mod config {
ExternalFullSwing, ExternalFullSwing,
} }
/// SWD access port protection setting.
#[non_exhaustive]
pub enum Debug {
/// Debugging is allowed (APPROTECT is disabled). Default.
Allowed,
/// Debugging is not allowed (APPROTECT is enabled).
Disallowed,
/// APPROTECT is not configured (neither to enable it or disable it).
/// This can be useful if you're already doing it by other means and
/// you don't want embassy-nrf to touch UICR.
NotConfigured,
}
/// Configuration for peripherals. Default configuration should work on any nRF chip. /// Configuration for peripherals. Default configuration should work on any nRF chip.
#[non_exhaustive] #[non_exhaustive]
pub struct Config { pub struct Config {
@ -152,6 +171,8 @@ pub mod config {
/// Time driver interrupt priority. Should be lower priority than softdevice if used. /// Time driver interrupt priority. Should be lower priority than softdevice if used.
#[cfg(feature = "_time-driver")] #[cfg(feature = "_time-driver")]
pub time_interrupt_priority: crate::interrupt::Priority, pub time_interrupt_priority: crate::interrupt::Priority,
/// Enable or disable the debug port.
pub debug: Debug,
} }
impl Default for Config { impl Default for Config {
@ -166,17 +187,204 @@ pub mod config {
gpiote_interrupt_priority: crate::interrupt::Priority::P0, gpiote_interrupt_priority: crate::interrupt::Priority::P0,
#[cfg(feature = "_time-driver")] #[cfg(feature = "_time-driver")]
time_interrupt_priority: crate::interrupt::Priority::P0, time_interrupt_priority: crate::interrupt::Priority::P0,
// In NS mode, default to NotConfigured, assuming the S firmware will do it.
#[cfg(feature = "_ns")]
debug: Debug::NotConfigured,
#[cfg(not(feature = "_ns"))]
debug: Debug::Allowed,
} }
} }
} }
} }
#[cfg(feature = "_nrf9160")]
#[allow(unused)]
mod consts {
pub const UICR_APPROTECT: *mut u32 = 0x00FF8000 as *mut u32;
pub const UICR_SECUREAPPROTECT: *mut u32 = 0x00FF802C as *mut u32;
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
}
#[cfg(feature = "_nrf5340-app")]
#[allow(unused)]
mod consts {
pub const UICR_APPROTECT: *mut u32 = 0x00FF8000 as *mut u32;
pub const UICR_SECUREAPPROTECT: *mut u32 = 0x00FF801C as *mut u32;
pub const UICR_NFCPINS: *mut u32 = 0x00FF8028 as *mut u32;
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
pub const APPROTECT_DISABLED: u32 = 0x50FA50FA;
}
#[cfg(feature = "_nrf5340-net")]
#[allow(unused)]
mod consts {
pub const UICR_APPROTECT: *mut u32 = 0x01FF8000 as *mut u32;
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
pub const APPROTECT_DISABLED: u32 = 0x50FA50FA;
}
#[cfg(feature = "_nrf52")]
#[allow(unused)]
mod consts {
pub const UICR_PSELRESET1: *mut u32 = 0x10001200 as *mut u32;
pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32;
pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32;
pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32;
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
pub const APPROTECT_DISABLED: u32 = 0x0000_005a;
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum WriteResult {
/// Word was written successfully, needs reset.
Written,
/// Word was already set to the value we wanted to write, nothing was done.
Noop,
/// Word is already set to something else, we couldn't write the desired value.
Failed,
}
unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult {
let curr_val = address.read_volatile();
if curr_val == value {
return WriteResult::Noop;
}
// We can only change `1` bits to `0` bits.
if curr_val & value != value {
return WriteResult::Failed;
}
// Writing to UICR can only change `1` bits to `0` bits.
// If this write would change `0` bits to `1` bits, we can't do it.
// It is only possible to do when erasing UICR, which is forbidden if
// APPROTECT is enabled.
if (!curr_val) & value != 0 {
panic!("Cannot write UICR address={:08x} value={:08x}", address as u32, value)
}
let nvmc = &*pac::NVMC::ptr();
nvmc.config.write(|w| w.wen().wen());
while nvmc.ready.read().ready().is_busy() {}
address.write_volatile(value);
while nvmc.ready.read().ready().is_busy() {}
nvmc.config.reset();
while nvmc.ready.read().ready().is_busy() {}
WriteResult::Written
}
/// Initialize peripherals with the provided configuration. This should only be called once at startup. /// Initialize peripherals with the provided configuration. This should only be called once at startup.
pub fn init(config: config::Config) -> Peripherals { pub fn init(config: config::Config) -> Peripherals {
// Do this first, so that it panics if user is calling `init` a second time // Do this first, so that it panics if user is calling `init` a second time
// before doing anything important. // before doing anything important.
let peripherals = Peripherals::take(); let peripherals = Peripherals::take();
let mut needs_reset = false;
// Setup debug protection.
match config.debug {
config::Debug::Allowed => {
#[cfg(feature = "_nrf52")]
unsafe {
let variant = (0x1000_0104 as *mut u32).read_volatile();
// Get the letter for the build code (b'A' .. b'F')
let build_code = (variant >> 8) as u8;
if build_code >= b'F' {
// Chips with build code F and higher (revision 3 and higher) have an
// improved APPROTECT ("hardware and software controlled access port protection")
// which needs explicit action by the firmware to keep it unlocked
// UICR.APPROTECT = SwDisabled
let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
needs_reset |= res == WriteResult::Written;
// APPROTECT.DISABLE = SwDisabled
(0x4000_0558 as *mut u32).write_volatile(consts::APPROTECT_DISABLED);
} else {
// nothing to do on older chips, debug is allowed by default.
}
}
#[cfg(feature = "_nrf5340")]
unsafe {
let p = &*pac::CTRLAP::ptr();
let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
needs_reset |= res == WriteResult::Written;
p.approtect.disable.write(|w| w.bits(consts::APPROTECT_DISABLED));
#[cfg(feature = "_nrf5340-app")]
{
let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_DISABLED);
needs_reset |= res == WriteResult::Written;
p.secureapprotect.disable.write(|w| w.bits(consts::APPROTECT_DISABLED));
}
}
// nothing to do on the nrf9160, debug is allowed by default.
}
config::Debug::Disallowed => unsafe {
// UICR.APPROTECT = Enabled
let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_ENABLED);
needs_reset |= res == WriteResult::Written;
#[cfg(any(feature = "_nrf5340-app", feature = "_nrf9160"))]
{
let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_ENABLED);
needs_reset |= res == WriteResult::Written;
}
},
config::Debug::NotConfigured => {}
}
#[cfg(feature = "_nrf52")]
unsafe {
let value = if cfg!(feature = "reset-pin-as-gpio") {
!0
} else {
chip::RESET_PIN
};
let res1 = uicr_write(consts::UICR_PSELRESET1, value);
let res2 = uicr_write(consts::UICR_PSELRESET2, value);
needs_reset |= res1 == WriteResult::Written || res2 == WriteResult::Written;
if res1 == WriteResult::Failed || res2 == WriteResult::Failed {
#[cfg(not(feature = "reset-pin-as-gpio"))]
warn!(
"You have requested enabling chip reset functionality on the reset pin, by not enabling the Cargo feature `reset-pin-as-gpio`.\n\
However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
To fix this, erase UICR manually, for example using `probe-rs-cli erase` or `nrfjprog --eraseuicr`."
);
#[cfg(feature = "reset-pin-as-gpio")]
warn!(
"You have requested using the reset pin as GPIO, by enabling the Cargo feature `reset-pin-as-gpio`.\n\
However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
To fix this, erase UICR manually, for example using `probe-rs-cli erase` or `nrfjprog --eraseuicr`."
);
}
}
#[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))]
unsafe {
let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { !0 };
let res = uicr_write(consts::UICR_NFCPINS, value);
needs_reset |= res == WriteResult::Written;
if res == WriteResult::Failed {
// with nfc-pins-as-gpio, this can never fail because we're writing all zero bits.
#[cfg(not(feature = "nfc-pins-as-gpio"))]
warn!(
"You have requested to use P0.09 and P0.10 pins for NFC, by not enabling the Cargo feature `nfc-pins-as-gpio`.\n\
However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
To fix this, erase UICR manually, for example using `probe-rs-cli erase` or `nrfjprog --eraseuicr`."
);
}
}
if needs_reset {
cortex_m::peripheral::SCB::sys_reset();
}
let r = unsafe { &*pac::CLOCK::ptr() }; let r = unsafe { &*pac::CLOCK::ptr() };
// Start HFCLK. // Start HFCLK.

View File

@ -85,23 +85,23 @@ impl<'d> Nvmc<'d> {
} }
fn enable_erase(&self) { fn enable_erase(&self) {
#[cfg(not(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns")))] #[cfg(not(feature = "_ns"))]
Self::regs().config.write(|w| w.wen().een()); Self::regs().config.write(|w| w.wen().een());
#[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] #[cfg(feature = "_ns")]
Self::regs().configns.write(|w| w.wen().een()); Self::regs().configns.write(|w| w.wen().een());
} }
fn enable_read(&self) { fn enable_read(&self) {
#[cfg(not(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns")))] #[cfg(not(feature = "_ns"))]
Self::regs().config.write(|w| w.wen().ren()); Self::regs().config.write(|w| w.wen().ren());
#[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] #[cfg(feature = "_ns")]
Self::regs().configns.write(|w| w.wen().ren()); Self::regs().configns.write(|w| w.wen().ren());
} }
fn enable_write(&self) { fn enable_write(&self) {
#[cfg(not(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns")))] #[cfg(not(feature = "_ns"))]
Self::regs().config.write(|w| w.wen().wen()); Self::regs().config.write(|w| w.wen().wen());
#[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] #[cfg(feature = "_ns")]
Self::regs().configns.write(|w| w.wen().wen()); Self::regs().configns.write(|w| w.wen().wen());
} }
} }