aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src/lib.rs')
-rw-r--r--embassy-nrf/src/lib.rs180
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")]
76mod time_driver; 87mod time_driver;
77 88
78#[cfg(not(feature = "_nrf54l"))] // TODO
79#[cfg(not(feature = "_nrf51"))] 89#[cfg(not(feature = "_nrf51"))]
80pub mod buffered_uarte; 90pub 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"))]
83pub mod egu; 93pub mod egu;
84pub mod gpio; 94pub mod gpio;
85#[cfg(not(feature = "_nrf54l"))] // TODO
86#[cfg(feature = "gpiote")] 95#[cfg(feature = "gpiote")]
87pub mod gpiote; 96pub mod gpiote;
88#[cfg(not(feature = "_nrf54l"))] // TODO 97#[cfg(not(feature = "_nrf54l"))] // TODO
@@ -100,9 +109,9 @@ pub mod ipc;
100pub mod nfct; 109pub mod nfct;
101#[cfg(not(feature = "_nrf54l"))] 110#[cfg(not(feature = "_nrf54l"))]
102pub mod nvmc; 111pub mod nvmc;
103#[cfg(feature = "nrf54l15-app-s")] 112#[cfg(all(feature = "_nrf54l", feature = "_s"))]
104pub mod rramc; 113pub mod rramc;
105#[cfg(feature = "nrf54l15-app-s")] 114#[cfg(all(feature = "_nrf54l", feature = "_s"))]
106pub use rramc as nvmc; 115pub 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"))]
120pub mod power; 129pub mod power;
121#[cfg(not(feature = "_nrf54l"))] // TODO
122pub mod ppi; 130pub 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")]
149pub mod embassy_net_802154_driver; 156pub mod embassy_net_802154_driver;
150 157
158#[cfg(all(feature = "_nrf54l", feature = "_s"))]
159pub mod cracen;
151#[cfg(not(feature = "_nrf54l"))] // TODO 160#[cfg(not(feature = "_nrf54l"))] // TODO
152#[cfg(feature = "_nrf5340")] 161#[cfg(feature = "_nrf5340")]
153pub mod reset; 162pub 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")))]
156pub mod rng; 165pub mod rng;
157#[cfg(not(feature = "_nrf54l"))] // TODO 166#[cfg(not(feature = "_nrf54l"))]
158pub mod rtc; 167pub 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")))]
161pub mod saadc; 169pub mod saadc;
162#[cfg(not(feature = "_nrf54l"))] // TODO
163#[cfg(not(feature = "_nrf51"))] 170#[cfg(not(feature = "_nrf51"))]
164pub mod spim; 171pub mod spim;
165#[cfg(not(feature = "_nrf54l"))] // TODO
166#[cfg(not(feature = "_nrf51"))] 172#[cfg(not(feature = "_nrf51"))]
167pub mod spis; 173pub mod spis;
168#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] 174#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))]
169pub mod temp; 175pub mod temp;
170#[cfg(not(feature = "_nrf54l"))] // TODO
171pub mod timer; 176pub mod timer;
172#[cfg(not(feature = "_nrf54l"))] // TODO
173#[cfg(not(feature = "_nrf51"))] 177#[cfg(not(feature = "_nrf51"))]
174pub mod twim; 178pub mod twim;
175#[cfg(not(feature = "_nrf54l"))] // TODO
176#[cfg(not(feature = "_nrf51"))] 179#[cfg(not(feature = "_nrf51"))]
177pub mod twis; 180pub mod twis;
178#[cfg(not(feature = "_nrf54l"))] // TODO
179#[cfg(not(feature = "_nrf51"))] 181#[cfg(not(feature = "_nrf51"))]
180pub mod uarte; 182pub 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")]
205mod chip; 210mod 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 {
284pub use chip::pac; 289pub use chip::pac;
285#[cfg(not(feature = "unstable-pac"))] 290#[cfg(not(feature = "unstable-pac"))]
286pub(crate) use chip::pac; 291pub(crate) use chip::pac;
287pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; 292pub use chip::{EASY_DMA_SIZE, Peripherals, peripherals};
288pub use embassy_hal_internal::{Peri, PeripheralType}; 293pub use embassy_hal_internal::{Peri, PeripheralType};
289 294
290pub use crate::chip::interrupt; 295pub use crate::chip::interrupt;
@@ -294,6 +299,15 @@ pub use crate::pac::NVIC_PRIO_BITS;
294pub mod config { 299pub 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))]
646enum WriteResult { 677pub 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")))]
656unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { 691pub 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")))]
661unsafe 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.
700pub 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