diff options
Diffstat (limited to 'embassy-nrf/src/lib.rs')
| -rw-r--r-- | embassy-nrf/src/lib.rs | 180 |
1 files changed, 143 insertions, 37 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 7c26a6184..584d0a0be 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![allow(async_fn_in_trait)] | 2 | #![allow(async_fn_in_trait)] |
| 3 | #![allow(unsafe_op_in_unsafe_fn)] | ||
| 3 | #![cfg_attr( | 4 | #![cfg_attr( |
| 4 | docsrs, | 5 | docsrs, |
| 5 | doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-nrf'>browse the `embassy-nrf` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (nRF52840 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" | 6 | doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-nrf'>browse the `embassy-nrf` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (nRF52840 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" |
| @@ -24,6 +25,11 @@ | |||
| 24 | feature = "nrf5340-net", | 25 | feature = "nrf5340-net", |
| 25 | feature = "nrf54l15-app-s", | 26 | feature = "nrf54l15-app-s", |
| 26 | feature = "nrf54l15-app-ns", | 27 | feature = "nrf54l15-app-ns", |
| 28 | feature = "nrf54l10-app-s", | ||
| 29 | feature = "nrf54l10-app-ns", | ||
| 30 | feature = "nrf54l05-app-s", | ||
| 31 | feature = "nrf54l05-app-ns", | ||
| 32 | feature = "nrf54lm20-app-s", | ||
| 27 | feature = "nrf9160-s", | 33 | feature = "nrf9160-s", |
| 28 | feature = "nrf9160-ns", | 34 | feature = "nrf9160-ns", |
| 29 | feature = "nrf9120-s", | 35 | feature = "nrf9120-s", |
| @@ -48,6 +54,11 @@ compile_error!( | |||
| 48 | nrf5340-net, | 54 | nrf5340-net, |
| 49 | nrf54l15-app-s, | 55 | nrf54l15-app-s, |
| 50 | nrf54l15-app-ns, | 56 | nrf54l15-app-ns, |
| 57 | nrf54l10-app-s, | ||
| 58 | nrf54l10-app-ns, | ||
| 59 | nrf54l05-app-s, | ||
| 60 | nrf54l05-app-ns, | ||
| 61 | nrf54lm20-app-s, | ||
| 51 | nrf9160-s, | 62 | nrf9160-s, |
| 52 | nrf9160-ns, | 63 | nrf9160-ns, |
| 53 | nrf9120-s, | 64 | nrf9120-s, |
| @@ -75,14 +86,12 @@ pub(crate) mod util; | |||
| 75 | #[cfg(feature = "_time-driver")] | 86 | #[cfg(feature = "_time-driver")] |
| 76 | mod time_driver; | 87 | mod time_driver; |
| 77 | 88 | ||
| 78 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 79 | #[cfg(not(feature = "_nrf51"))] | 89 | #[cfg(not(feature = "_nrf51"))] |
| 80 | pub mod buffered_uarte; | 90 | pub mod buffered_uarte; |
| 81 | #[cfg(not(feature = "_nrf54l"))] // TODO | 91 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 82 | #[cfg(not(feature = "_nrf51"))] | 92 | #[cfg(not(feature = "_nrf51"))] |
| 83 | pub mod egu; | 93 | pub mod egu; |
| 84 | pub mod gpio; | 94 | pub mod gpio; |
| 85 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 86 | #[cfg(feature = "gpiote")] | 95 | #[cfg(feature = "gpiote")] |
| 87 | pub mod gpiote; | 96 | pub mod gpiote; |
| 88 | #[cfg(not(feature = "_nrf54l"))] // TODO | 97 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -100,9 +109,9 @@ pub mod ipc; | |||
| 100 | pub mod nfct; | 109 | pub mod nfct; |
| 101 | #[cfg(not(feature = "_nrf54l"))] | 110 | #[cfg(not(feature = "_nrf54l"))] |
| 102 | pub mod nvmc; | 111 | pub mod nvmc; |
| 103 | #[cfg(feature = "nrf54l15-app-s")] | 112 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 104 | pub mod rramc; | 113 | pub mod rramc; |
| 105 | #[cfg(feature = "nrf54l15-app-s")] | 114 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 106 | pub use rramc as nvmc; | 115 | pub use rramc as nvmc; |
| 107 | #[cfg(not(feature = "_nrf54l"))] // TODO | 116 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 108 | #[cfg(any( | 117 | #[cfg(any( |
| @@ -118,9 +127,7 @@ pub mod pdm; | |||
| 118 | #[cfg(not(feature = "_nrf54l"))] // TODO | 127 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 119 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] | 128 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] |
| 120 | pub mod power; | 129 | pub mod power; |
| 121 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 122 | pub mod ppi; | 130 | pub mod ppi; |
| 123 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 124 | #[cfg(not(any( | 131 | #[cfg(not(any( |
| 125 | feature = "_nrf51", | 132 | feature = "_nrf51", |
| 126 | feature = "nrf52805", | 133 | feature = "nrf52805", |
| @@ -148,34 +155,29 @@ pub mod radio; | |||
| 148 | #[cfg(feature = "_net-driver")] | 155 | #[cfg(feature = "_net-driver")] |
| 149 | pub mod embassy_net_802154_driver; | 156 | pub mod embassy_net_802154_driver; |
| 150 | 157 | ||
| 158 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 159 | pub mod cracen; | ||
| 151 | #[cfg(not(feature = "_nrf54l"))] // TODO | 160 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 152 | #[cfg(feature = "_nrf5340")] | 161 | #[cfg(feature = "_nrf5340")] |
| 153 | pub mod reset; | 162 | pub mod reset; |
| 154 | #[cfg(not(feature = "_nrf54l"))] // TODO | 163 | #[cfg(not(feature = "_nrf54l"))] |
| 155 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 164 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 156 | pub mod rng; | 165 | pub mod rng; |
| 157 | #[cfg(not(feature = "_nrf54l"))] // TODO | 166 | #[cfg(not(feature = "_nrf54l"))] |
| 158 | pub mod rtc; | 167 | pub mod rtc; |
| 159 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 160 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] | 168 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] |
| 161 | pub mod saadc; | 169 | pub mod saadc; |
| 162 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 163 | #[cfg(not(feature = "_nrf51"))] | 170 | #[cfg(not(feature = "_nrf51"))] |
| 164 | pub mod spim; | 171 | pub mod spim; |
| 165 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 166 | #[cfg(not(feature = "_nrf51"))] | 172 | #[cfg(not(feature = "_nrf51"))] |
| 167 | pub mod spis; | 173 | pub mod spis; |
| 168 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 174 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 169 | pub mod temp; | 175 | pub mod temp; |
| 170 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 171 | pub mod timer; | 176 | pub mod timer; |
| 172 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 173 | #[cfg(not(feature = "_nrf51"))] | 177 | #[cfg(not(feature = "_nrf51"))] |
| 174 | pub mod twim; | 178 | pub mod twim; |
| 175 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 176 | #[cfg(not(feature = "_nrf51"))] | 179 | #[cfg(not(feature = "_nrf51"))] |
| 177 | pub mod twis; | 180 | pub mod twis; |
| 178 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 179 | #[cfg(not(feature = "_nrf51"))] | 181 | #[cfg(not(feature = "_nrf51"))] |
| 180 | pub mod uarte; | 182 | pub mod uarte; |
| 181 | #[cfg(not(feature = "_nrf54l"))] // TODO | 183 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -200,6 +202,9 @@ pub mod wdt; | |||
| 200 | #[cfg_attr(feature = "_nrf5340-app", path = "chips/nrf5340_app.rs")] | 202 | #[cfg_attr(feature = "_nrf5340-app", path = "chips/nrf5340_app.rs")] |
| 201 | #[cfg_attr(feature = "_nrf5340-net", path = "chips/nrf5340_net.rs")] | 203 | #[cfg_attr(feature = "_nrf5340-net", path = "chips/nrf5340_net.rs")] |
| 202 | #[cfg_attr(feature = "_nrf54l15-app", path = "chips/nrf54l15_app.rs")] | 204 | #[cfg_attr(feature = "_nrf54l15-app", path = "chips/nrf54l15_app.rs")] |
| 205 | #[cfg_attr(feature = "_nrf54l10-app", path = "chips/nrf54l10_app.rs")] | ||
| 206 | #[cfg_attr(feature = "_nrf54l05-app", path = "chips/nrf54l05_app.rs")] | ||
| 207 | #[cfg_attr(feature = "_nrf54lm20-app", path = "chips/nrf54lm20_app.rs")] | ||
| 203 | #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] | 208 | #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] |
| 204 | #[cfg_attr(feature = "_nrf9120", path = "chips/nrf9120.rs")] | 209 | #[cfg_attr(feature = "_nrf9120", path = "chips/nrf9120.rs")] |
| 205 | mod chip; | 210 | mod chip; |
| @@ -252,7 +257,7 @@ macro_rules! bind_interrupts { | |||
| 252 | 257 | ||
| 253 | $( | 258 | $( |
| 254 | #[allow(non_snake_case)] | 259 | #[allow(non_snake_case)] |
| 255 | #[no_mangle] | 260 | #[unsafe(no_mangle)] |
| 256 | $(#[cfg($cond_irq)])? | 261 | $(#[cfg($cond_irq)])? |
| 257 | unsafe extern "C" fn $irq() { | 262 | unsafe extern "C" fn $irq() { |
| 258 | unsafe { | 263 | unsafe { |
| @@ -284,7 +289,7 @@ macro_rules! bind_interrupts { | |||
| 284 | pub use chip::pac; | 289 | pub use chip::pac; |
| 285 | #[cfg(not(feature = "unstable-pac"))] | 290 | #[cfg(not(feature = "unstable-pac"))] |
| 286 | pub(crate) use chip::pac; | 291 | pub(crate) use chip::pac; |
| 287 | pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; | 292 | pub use chip::{EASY_DMA_SIZE, Peripherals, peripherals}; |
| 288 | pub use embassy_hal_internal::{Peri, PeripheralType}; | 293 | pub use embassy_hal_internal::{Peri, PeripheralType}; |
| 289 | 294 | ||
| 290 | pub use crate::chip::interrupt; | 295 | pub use crate::chip::interrupt; |
| @@ -294,6 +299,15 @@ pub use crate::pac::NVIC_PRIO_BITS; | |||
| 294 | pub mod config { | 299 | pub mod config { |
| 295 | //! Configuration options used when initializing the HAL. | 300 | //! Configuration options used when initializing the HAL. |
| 296 | 301 | ||
| 302 | /// Clock speed | ||
| 303 | #[cfg(feature = "_nrf54l")] | ||
| 304 | pub enum ClockSpeed { | ||
| 305 | /// Run at 128 MHz. | ||
| 306 | CK128, | ||
| 307 | /// Run at 64 MHz. | ||
| 308 | CK64, | ||
| 309 | } | ||
| 310 | |||
| 297 | /// High frequency clock source. | 311 | /// High frequency clock source. |
| 298 | pub enum HfclkSource { | 312 | pub enum HfclkSource { |
| 299 | /// Internal source | 313 | /// Internal source |
| @@ -406,9 +420,10 @@ pub mod config { | |||
| 406 | /// Settings for the internal capacitors. | 420 | /// Settings for the internal capacitors. |
| 407 | #[cfg(feature = "nrf5340-app-s")] | 421 | #[cfg(feature = "nrf5340-app-s")] |
| 408 | pub struct InternalCapacitors { | 422 | pub struct InternalCapacitors { |
| 409 | /// Config for the internal capacitors on pins XC1 and XC2. | 423 | /// Config for the internal capacitors on pins XC1 and XC2. Pass `None` to not touch it. |
| 410 | pub hfxo: Option<HfxoCapacitance>, | 424 | pub hfxo: Option<HfxoCapacitance>, |
| 411 | /// Config for the internal capacitors between pins XL1 and XL2. | 425 | /// Config for the internal capacitors between pins XL1 and XL2. Pass `None` to not touch |
| 426 | /// it. | ||
| 412 | pub lfxo: Option<LfxoCapacitance>, | 427 | pub lfxo: Option<LfxoCapacitance>, |
| 413 | } | 428 | } |
| 414 | 429 | ||
| @@ -416,6 +431,8 @@ pub mod config { | |||
| 416 | #[cfg(feature = "nrf5340-app-s")] | 431 | #[cfg(feature = "nrf5340-app-s")] |
| 417 | #[derive(Copy, Clone)] | 432 | #[derive(Copy, Clone)] |
| 418 | pub enum HfxoCapacitance { | 433 | pub enum HfxoCapacitance { |
| 434 | /// Use external capacitors | ||
| 435 | External, | ||
| 419 | /// 7.0 pF | 436 | /// 7.0 pF |
| 420 | _7_0pF, | 437 | _7_0pF, |
| 421 | /// 7.5 pF | 438 | /// 7.5 pF |
| @@ -475,8 +492,9 @@ pub mod config { | |||
| 475 | #[cfg(feature = "nrf5340-app-s")] | 492 | #[cfg(feature = "nrf5340-app-s")] |
| 476 | impl HfxoCapacitance { | 493 | impl HfxoCapacitance { |
| 477 | /// The capacitance value times two. | 494 | /// The capacitance value times two. |
| 478 | pub(crate) const fn value2(self) -> i32 { | 495 | pub(crate) fn value2(self) -> i32 { |
| 479 | match self { | 496 | match self { |
| 497 | HfxoCapacitance::External => unreachable!(), | ||
| 480 | HfxoCapacitance::_7_0pF => 14, | 498 | HfxoCapacitance::_7_0pF => 14, |
| 481 | HfxoCapacitance::_7_5pF => 15, | 499 | HfxoCapacitance::_7_5pF => 15, |
| 482 | HfxoCapacitance::_8_0pF => 16, | 500 | HfxoCapacitance::_8_0pF => 16, |
| @@ -506,11 +524,17 @@ pub mod config { | |||
| 506 | HfxoCapacitance::_20_0pF => 40, | 524 | HfxoCapacitance::_20_0pF => 40, |
| 507 | } | 525 | } |
| 508 | } | 526 | } |
| 527 | |||
| 528 | pub(crate) fn external(self) -> bool { | ||
| 529 | matches!(self, Self::External) | ||
| 530 | } | ||
| 509 | } | 531 | } |
| 510 | 532 | ||
| 511 | /// Internal capacitance value for the LFXO. | 533 | /// Internal capacitance value for the LFXO. |
| 512 | #[cfg(feature = "nrf5340-app-s")] | 534 | #[cfg(feature = "nrf5340-app-s")] |
| 513 | pub enum LfxoCapacitance { | 535 | pub enum LfxoCapacitance { |
| 536 | /// Use external capacitors | ||
| 537 | External = 0, | ||
| 514 | /// 6 pF | 538 | /// 6 pF |
| 515 | _6pF = 1, | 539 | _6pF = 1, |
| 516 | /// 7 pF | 540 | /// 7 pF |
| @@ -523,6 +547,7 @@ pub mod config { | |||
| 523 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { | 547 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { |
| 524 | fn from(t: LfxoCapacitance) -> Self { | 548 | fn from(t: LfxoCapacitance) -> Self { |
| 525 | match t { | 549 | match t { |
| 550 | LfxoCapacitance::External => Self::EXTERNAL, | ||
| 526 | LfxoCapacitance::_6pF => Self::C6PF, | 551 | LfxoCapacitance::_6pF => Self::C6PF, |
| 527 | LfxoCapacitance::_7pF => Self::C7PF, | 552 | LfxoCapacitance::_7pF => Self::C7PF, |
| 528 | LfxoCapacitance::_9pF => Self::C9PF, | 553 | LfxoCapacitance::_9pF => Self::C9PF, |
| @@ -552,6 +577,9 @@ pub mod config { | |||
| 552 | pub time_interrupt_priority: crate::interrupt::Priority, | 577 | pub time_interrupt_priority: crate::interrupt::Priority, |
| 553 | /// Enable or disable the debug port. | 578 | /// Enable or disable the debug port. |
| 554 | pub debug: Debug, | 579 | pub debug: Debug, |
| 580 | /// Clock speed configuration. | ||
| 581 | #[cfg(feature = "_nrf54l")] | ||
| 582 | pub clock_speed: ClockSpeed, | ||
| 555 | } | 583 | } |
| 556 | 584 | ||
| 557 | impl Default for Config { | 585 | impl Default for Config { |
| @@ -592,6 +620,8 @@ pub mod config { | |||
| 592 | debug: Debug::NotConfigured, | 620 | debug: Debug::NotConfigured, |
| 593 | #[cfg(not(feature = "_ns"))] | 621 | #[cfg(not(feature = "_ns"))] |
| 594 | debug: Debug::Allowed, | 622 | debug: Debug::Allowed, |
| 623 | #[cfg(feature = "_nrf54l")] | ||
| 624 | clock_speed: ClockSpeed::CK64, | ||
| 595 | } | 625 | } |
| 596 | } | 626 | } |
| 597 | } | 627 | } |
| @@ -640,10 +670,11 @@ mod consts { | |||
| 640 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; | 670 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; |
| 641 | } | 671 | } |
| 642 | 672 | ||
| 673 | /// Result from writing UICR. | ||
| 643 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] | 674 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] |
| 644 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | 675 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| 645 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 676 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 646 | enum WriteResult { | 677 | pub enum WriteResult { |
| 647 | /// Word was written successfully, needs reset. | 678 | /// Word was written successfully, needs reset. |
| 648 | Written, | 679 | Written, |
| 649 | /// Word was already set to the value we wanted to write, nothing was done. | 680 | /// Word was already set to the value we wanted to write, nothing was done. |
| @@ -652,13 +683,21 @@ enum WriteResult { | |||
| 652 | Failed, | 683 | Failed, |
| 653 | } | 684 | } |
| 654 | 685 | ||
| 686 | /// Write the UICR value at the provided address, ensuring that flash | ||
| 687 | /// settings are correctly apply to persist the value. | ||
| 688 | /// | ||
| 689 | /// Safety: the address must be a valid UICR register. | ||
| 655 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] | 690 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] |
| 656 | unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { | 691 | pub unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { |
| 657 | uicr_write_masked(address, value, 0xFFFF_FFFF) | 692 | uicr_write_masked(address, value, 0xFFFF_FFFF) |
| 658 | } | 693 | } |
| 659 | 694 | ||
| 660 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] | 695 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] |
| 661 | unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult { | 696 | /// Write the UICR value at the provided address, ensuring that flash |
| 697 | /// settings are correctly apply to persist the value. | ||
| 698 | /// | ||
| 699 | /// Safety: the address must be a valid UICR register. | ||
| 700 | pub unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult { | ||
| 662 | let curr_val = address.read_volatile(); | 701 | let curr_val = address.read_volatile(); |
| 663 | if curr_val & mask == value & mask { | 702 | if curr_val & mask == value & mask { |
| 664 | return WriteResult::Noop; | 703 | return WriteResult::Noop; |
| @@ -698,6 +737,23 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 698 | #[allow(unused_mut)] | 737 | #[allow(unused_mut)] |
| 699 | let mut needs_reset = false; | 738 | let mut needs_reset = false; |
| 700 | 739 | ||
| 740 | // set clock speed | ||
| 741 | #[cfg(feature = "_nrf54l")] | ||
| 742 | { | ||
| 743 | #[cfg(feature = "_s")] | ||
| 744 | let regs = pac::OSCILLATORS_S; | ||
| 745 | #[cfg(feature = "_ns")] | ||
| 746 | let regs = pac::OSCILLATORS_NS; | ||
| 747 | |||
| 748 | use pac::oscillators::vals::Freq; | ||
| 749 | regs.pll().freq().write(|w| { | ||
| 750 | w.set_freq(match config.clock_speed { | ||
| 751 | config::ClockSpeed::CK64 => Freq::CK64M, | ||
| 752 | config::ClockSpeed::CK128 => Freq::CK128M, | ||
| 753 | }); | ||
| 754 | }); | ||
| 755 | } | ||
| 756 | |||
| 701 | // Workaround used in the nrf mdk: file system_nrf91.c , function SystemInit(), after `#if !defined(NRF_SKIP_UICR_HFXO_WORKAROUND)` | 757 | // Workaround used in the nrf mdk: file system_nrf91.c , function SystemInit(), after `#if !defined(NRF_SKIP_UICR_HFXO_WORKAROUND)` |
| 702 | #[cfg(all(feature = "_nrf91", feature = "_s"))] | 758 | #[cfg(all(feature = "_nrf91", feature = "_s"))] |
| 703 | { | 759 | { |
| @@ -720,6 +776,53 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 720 | } | 776 | } |
| 721 | } | 777 | } |
| 722 | 778 | ||
| 779 | // Apply trimming values from the FICR. | ||
| 780 | #[cfg(any( | ||
| 781 | all(feature = "_nrf5340-app", feature = "_s"), | ||
| 782 | all(feature = "_nrf54l", feature = "_s"), | ||
| 783 | feature = "_nrf5340-net", | ||
| 784 | ))] | ||
| 785 | { | ||
| 786 | #[cfg(feature = "_nrf5340")] | ||
| 787 | let n = 32; | ||
| 788 | #[cfg(feature = "_nrf54l")] | ||
| 789 | let n = 64; | ||
| 790 | for i in 0..n { | ||
| 791 | let info = pac::FICR.trimcnf(i); | ||
| 792 | let addr = info.addr().read(); | ||
| 793 | if addr == 0 || addr == 0xFFFF_FFFF { | ||
| 794 | break; | ||
| 795 | } | ||
| 796 | unsafe { | ||
| 797 | (addr as *mut u32).write_volatile(info.data().read()); | ||
| 798 | } | ||
| 799 | } | ||
| 800 | } | ||
| 801 | |||
| 802 | // Workaround for anomaly 66 | ||
| 803 | #[cfg(feature = "_nrf52")] | ||
| 804 | { | ||
| 805 | let ficr = pac::FICR; | ||
| 806 | let temp = pac::TEMP; | ||
| 807 | temp.a(0).write_value(ficr.temp().a0().read().0); | ||
| 808 | temp.a(1).write_value(ficr.temp().a1().read().0); | ||
| 809 | temp.a(2).write_value(ficr.temp().a2().read().0); | ||
| 810 | temp.a(3).write_value(ficr.temp().a3().read().0); | ||
| 811 | temp.a(4).write_value(ficr.temp().a4().read().0); | ||
| 812 | temp.a(5).write_value(ficr.temp().a5().read().0); | ||
| 813 | temp.b(0).write_value(ficr.temp().b0().read().0); | ||
| 814 | temp.b(1).write_value(ficr.temp().b1().read().0); | ||
| 815 | temp.b(2).write_value(ficr.temp().b2().read().0); | ||
| 816 | temp.b(3).write_value(ficr.temp().b3().read().0); | ||
| 817 | temp.b(4).write_value(ficr.temp().b4().read().0); | ||
| 818 | temp.b(5).write_value(ficr.temp().b5().read().0); | ||
| 819 | temp.t(0).write_value(ficr.temp().t0().read().0); | ||
| 820 | temp.t(1).write_value(ficr.temp().t1().read().0); | ||
| 821 | temp.t(2).write_value(ficr.temp().t2().read().0); | ||
| 822 | temp.t(3).write_value(ficr.temp().t3().read().0); | ||
| 823 | temp.t(4).write_value(ficr.temp().t4().read().0); | ||
| 824 | } | ||
| 825 | |||
| 723 | // GLITCHDET is only accessible for secure code | 826 | // GLITCHDET is only accessible for secure code |
| 724 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | 827 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 725 | { | 828 | { |
| @@ -742,9 +845,9 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 742 | // Chips with a certain chip type-specific build code or higher have an | 845 | // Chips with a certain chip type-specific build code or higher have an |
| 743 | // improved APPROTECT ("hardware and software controlled access port protection") | 846 | // improved APPROTECT ("hardware and software controlled access port protection") |
| 744 | // which needs explicit action by the firmware to keep it unlocked | 847 | // which needs explicit action by the firmware to keep it unlocked |
| 745 | // See https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/working-with-the-nrf52-series-improved-approtect | 848 | // See https://docs.nordicsemi.com/bundle/ps_nrf52840/page/dif.html#d402e184 |
| 746 | 849 | ||
| 747 | // UICR.APPROTECT = SwDisabled | 850 | // UICR.APPROTECT = HwDisabled |
| 748 | let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED); | 851 | let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED); |
| 749 | needs_reset |= res == WriteResult::Written; | 852 | needs_reset |= res == WriteResult::Written; |
| 750 | // APPROTECT.DISABLE = SwDisabled | 853 | // APPROTECT.DISABLE = SwDisabled |
| @@ -899,7 +1002,7 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 899 | } | 1002 | } |
| 900 | } | 1003 | } |
| 901 | 1004 | ||
| 902 | #[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))] | 1005 | #[cfg(any(feature = "_nrf52", all(feature = "_nrf5340-app", feature = "_s")))] |
| 903 | unsafe { | 1006 | unsafe { |
| 904 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 }; | 1007 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 }; |
| 905 | let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1); | 1008 | let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1); |
| @@ -953,17 +1056,21 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 953 | #[cfg(feature = "nrf5340-app-s")] | 1056 | #[cfg(feature = "nrf5340-app-s")] |
| 954 | { | 1057 | { |
| 955 | if let Some(cap) = config.internal_capacitors.hfxo { | 1058 | if let Some(cap) = config.internal_capacitors.hfxo { |
| 956 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; | 1059 | if cap.external() { |
| 957 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; | 1060 | pac::OSCILLATORS.xosc32mcaps().write(|w| w.set_enable(false)); |
| 958 | // slope is a signed 5-bit integer | 1061 | } else { |
| 959 | if slope >= 16 { | 1062 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; |
| 960 | slope -= 32; | 1063 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; |
| 1064 | // slope is a signed 5-bit integer | ||
| 1065 | if slope >= 16 { | ||
| 1066 | slope -= 32; | ||
| 1067 | } | ||
| 1068 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 1069 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 1070 | w.set_capvalue(capvalue as u8); | ||
| 1071 | w.set_enable(true); | ||
| 1072 | }); | ||
| 961 | } | 1073 | } |
| 962 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 963 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 964 | w.set_capvalue(capvalue as u8); | ||
| 965 | w.set_enable(true); | ||
| 966 | }); | ||
| 967 | } | 1074 | } |
| 968 | if let Some(cap) = config.internal_capacitors.lfxo { | 1075 | if let Some(cap) = config.internal_capacitors.lfxo { |
| 969 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); | 1076 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); |
| @@ -1115,7 +1222,6 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 1115 | } | 1222 | } |
| 1116 | 1223 | ||
| 1117 | // Init GPIOTE | 1224 | // Init GPIOTE |
| 1118 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 1119 | #[cfg(feature = "gpiote")] | 1225 | #[cfg(feature = "gpiote")] |
| 1120 | gpiote::init(config.gpiote_interrupt_priority); | 1226 | gpiote::init(config.gpiote_interrupt_priority); |
| 1121 | 1227 | ||
