1#![no_std]
2#![allow(async_fn_in_trait)]
3#![cfg_attr(
4 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)]
7#![doc = include_str!("../README.md")]
8#![warn(missing_docs)]
9
10#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
12
13#[cfg(not(any(
14 feature = "_nrf51",
15 feature = "nrf52805",
16 feature = "nrf52810",
17 feature = "nrf52811",
18 feature = "nrf52820",
19 feature = "nrf52832",
20 feature = "nrf52833",
21 feature = "nrf52840",
22 feature = "nrf5340-app-s",
23 feature = "nrf5340-app-ns",
24 feature = "nrf5340-net",
25 feature = "nrf54l15-app-s",
26 feature = "nrf54l15-app-ns",
27 feature = "nrf9160-s",
28 feature = "nrf9160-ns",
29 feature = "nrf9120-s",
30 feature = "nrf9120-ns",
31 feature = "nrf9151-s",
32 feature = "nrf9151-ns",
33 feature = "nrf9161-s",
34 feature = "nrf9161-ns",
35)))]
36compile_error!(
37 "No chip feature activated. You must activate exactly one of the following features:
38 nrf51,
39 nrf52805,
40 nrf52810,
41 nrf52811,
42 nrf52820,
43 nrf52832,
44 nrf52833,
45 nrf52840,
46 nrf5340-app-s,
47 nrf5340-app-ns,
48 nrf5340-net,
49 nrf54l15-app-s,
50 nrf54l15-app-ns,
51 nrf9160-s,
52 nrf9160-ns,
53 nrf9120-s,
54 nrf9120-ns,
55 nrf9151-s,
56 nrf9151-ns,
57 nrf9161-s,
58 nrf9161-ns,
59 "
60);
61
62#[cfg(all(feature = "reset-pin-as-gpio", not(feature = "_nrf52")))]
63compile_error!("feature `reset-pin-as-gpio` is only valid for nRF52 series chips.");
64
65#[cfg(all(feature = "nfc-pins-as-gpio", not(any(feature = "_nrf52", feature = "_nrf5340-app"))))]
66compile_error!("feature `nfc-pins-as-gpio` is only valid for nRF52, or nRF53's application core.");
67
68#[cfg(all(feature = "lfxo-pins-as-gpio", not(feature = "_nrf5340")))]
69compile_error!("feature `lfxo-pins-as-gpio` is only valid for nRF53 series chips.");
70
71pub(crate) mod fmt;
73pub(crate) mod util;
74
75#[cfg(feature = "_time-driver")]
76mod time_driver;
77
78#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
80pub mod buffered_uarte;
81#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
83pub mod egu;
84pub mod gpio;
85#[cfg(not(feature = "_nrf54l"))] #[cfg(feature = "gpiote")]
87pub mod gpiote;
88#[cfg(not(feature = "_nrf54l"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
90pub mod i2s;
91#[cfg(feature = "_nrf5340")]
92pub mod ipc;
93#[cfg(not(feature = "_nrf54l"))] #[cfg(any(
95 feature = "nrf52832",
96 feature = "nrf52833",
97 feature = "nrf52840",
98 feature = "_nrf5340-app"
99))]
100pub mod nfct;
101#[cfg(not(feature = "_nrf54l"))]
102pub mod nvmc;
103#[cfg(feature = "nrf54l15-app-s")]
104pub mod rramc;
105#[cfg(feature = "nrf54l15-app-s")]
106pub use rramc as nvmc;
107#[cfg(not(feature = "_nrf54l"))] #[cfg(any(
109 feature = "nrf52810",
110 feature = "nrf52811",
111 feature = "nrf52832",
112 feature = "nrf52833",
113 feature = "nrf52840",
114 feature = "_nrf5340-app",
115 feature = "_nrf91",
116))]
117pub mod pdm;
118#[cfg(not(feature = "_nrf54l"))] #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))]
120pub mod power;
121#[cfg(not(feature = "_nrf54l"))] pub mod ppi;
123#[cfg(not(feature = "_nrf54l"))] #[cfg(not(any(
125 feature = "_nrf51",
126 feature = "nrf52805",
127 feature = "nrf52820",
128 feature = "_nrf5340-net"
129)))]
130pub mod pwm;
131#[cfg(not(feature = "_nrf54l"))] #[cfg(not(any(feature = "_nrf51", feature = "_nrf91", feature = "_nrf5340-net")))]
133pub mod qdec;
134#[cfg(not(feature = "_nrf54l"))] #[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))]
136pub mod qspi;
137#[cfg(not(feature = "_nrf54l"))] #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340-app")))]
139pub mod radio;
140
141#[cfg(any(
142 feature = "nrf52811",
143 feature = "nrf52820",
144 feature = "nrf52833",
145 feature = "nrf52840",
146 feature = "_nrf5340-net"
147))]
148#[cfg(feature = "_net-driver")]
149pub mod embassy_net_802154_driver;
150
151#[cfg(not(feature = "_nrf54l"))] #[cfg(feature = "_nrf5340")]
153pub mod reset;
154#[cfg(not(feature = "_nrf54l"))] #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))]
156pub mod rng;
157#[cfg(not(feature = "_nrf54l"))] pub mod rtc;
159#[cfg(not(feature = "_nrf54l"))] #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))]
161pub mod saadc;
162#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
164pub mod spim;
165#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
167pub mod spis;
168#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))]
169pub mod temp;
170#[cfg(not(feature = "_nrf54l"))] pub mod timer;
172#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
174pub mod twim;
175#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
177pub mod twis;
178#[cfg(not(feature = "_nrf54l"))] #[cfg(not(feature = "_nrf51"))]
180pub mod uarte;
181#[cfg(not(feature = "_nrf54l"))] #[cfg(any(
183 feature = "_nrf5340-app",
184 feature = "nrf52820",
185 feature = "nrf52833",
186 feature = "nrf52840"
187))]
188pub mod usb;
189pub mod wdt;
190
191#[cfg_attr(feature = "_nrf51", path = "chips/nrf51.rs")]
193#[cfg_attr(feature = "nrf52805", path = "chips/nrf52805.rs")]
194#[cfg_attr(feature = "nrf52810", path = "chips/nrf52810.rs")]
195#[cfg_attr(feature = "nrf52811", path = "chips/nrf52811.rs")]
196#[cfg_attr(feature = "nrf52820", path = "chips/nrf52820.rs")]
197#[cfg_attr(feature = "nrf52832", path = "chips/nrf52832.rs")]
198#[cfg_attr(feature = "nrf52833", path = "chips/nrf52833.rs")]
199#[cfg_attr(feature = "nrf52840", path = "chips/nrf52840.rs")]
200#[cfg_attr(feature = "_nrf5340-app", path = "chips/nrf5340_app.rs")]
201#[cfg_attr(feature = "_nrf5340-net", path = "chips/nrf5340_net.rs")]
202#[cfg_attr(feature = "_nrf54l15-app", path = "chips/nrf54l15_app.rs")]
203#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
204#[cfg_attr(feature = "_nrf9120", path = "chips/nrf9120.rs")]
205mod chip;
206
207#[macro_export]
239macro_rules! bind_interrupts {
240 ($(#[$attr:meta])* $vis:vis struct $name:ident {
241 $(
242 $(#[cfg($cond_irq:meta)])?
243 $irq:ident => $(
244 $(#[cfg($cond_handler:meta)])?
245 $handler:ty
246 ),*;
247 )*
248 }) => {
249 #[derive(Copy, Clone)]
250 $(#[$attr])*
251 $vis struct $name;
252
253 $(
254 #[allow(non_snake_case)]
255 #[no_mangle]
256 $(#[cfg($cond_irq)])?
257 unsafe extern "C" fn $irq() {
258 unsafe {
259 $(
260 $(#[cfg($cond_handler)])?
261 <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
262
263 )*
264 }
265 }
266
267 $(#[cfg($cond_irq)])?
268 $crate::bind_interrupts!(@inner
269 $(
270 $(#[cfg($cond_handler)])?
271 unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
272 )*
273 );
274 )*
275 };
276 (@inner $($t:tt)*) => {
277 $($t)*
278 }
279}
280
281#[cfg(feature = "unstable-pac")]
284pub use chip::pac;
285#[cfg(not(feature = "unstable-pac"))]
286pub(crate) use chip::pac;
287pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
288pub use embassy_hal_internal::{Peri, PeripheralType};
289
290pub use crate::chip::interrupt;
291#[cfg(feature = "rt")]
292pub use crate::pac::NVIC_PRIO_BITS;
293
294pub mod config {
295 pub enum HfclkSource {
299 Internal,
301 ExternalXtal,
303 }
304
305 pub enum LfclkSource {
307 InternalRC,
309 #[cfg(not(feature = "_nrf91"))]
311 Synthesized,
312 #[cfg(not(feature = "lfxo-pins-as-gpio"))]
314 ExternalXtal,
315 #[cfg(not(any(feature = "lfxo-pins-as-gpio", feature = "_nrf91", feature = "_nrf54l")))]
317 ExternalLowSwing,
318 #[cfg(not(any(feature = "lfxo-pins-as-gpio", feature = "_nrf91", feature = "_nrf54l")))]
320 ExternalFullSwing,
321 }
322
323 #[non_exhaustive]
325 pub enum Debug {
326 Allowed,
328 Disallowed,
330 NotConfigured,
334 }
335
336 #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
338 pub struct DcdcConfig {
339 #[cfg(feature = "nrf52840")]
341 pub reg0: bool,
342 #[cfg(any(feature = "nrf52840", feature = "nrf52833"))]
344 pub reg0_voltage: Option<Reg0Voltage>,
345 pub reg1: bool,
347 }
348
349 #[cfg(any(feature = "nrf52840", feature = "nrf52833"))]
351 pub enum Reg0Voltage {
352 _1V8 = 0,
354 _2V1 = 1,
356 _2V4 = 2,
358 _2V7 = 3,
360 _3V0 = 4,
362 _3V3 = 5,
364 }
366
367 #[cfg(feature = "_nrf5340-app")]
369 pub struct DcdcConfig {
370 pub regh: bool,
372 #[cfg(feature = "nrf5340-app-s")]
374 pub regh_voltage: Option<ReghVoltage>,
375 pub regmain: bool,
377 pub regradio: bool,
379 }
380
381 #[cfg(feature = "nrf5340-app-s")]
383 pub enum ReghVoltage {
384 _1V8 = 0,
386 _2V1 = 1,
388 _2V4 = 2,
390 _2V7 = 3,
392 _3V0 = 4,
394 _3V3 = 5,
396 }
398
399 #[cfg(feature = "_nrf91")]
401 pub struct DcdcConfig {
402 pub regmain: bool,
404 }
405
406 #[cfg(feature = "nrf5340-app-s")]
408 pub struct InternalCapacitors {
409 pub hfxo: Option<HfxoCapacitance>,
411 pub lfxo: Option<LfxoCapacitance>,
413 }
414
415 #[cfg(feature = "nrf5340-app-s")]
417 #[derive(Copy, Clone)]
418 pub enum HfxoCapacitance {
419 _7_0pF,
421 _7_5pF,
423 _8_0pF,
425 _8_5pF,
427 _9_0pF,
429 _9_5pF,
431 _10_0pF,
433 _10_5pF,
435 _11_0pF,
437 _11_5pF,
439 _12_0pF,
441 _12_5pF,
443 _13_0pF,
445 _13_5pF,
447 _14_0pF,
449 _14_5pF,
451 _15_0pF,
453 _15_5pF,
455 _16_0pF,
457 _16_5pF,
459 _17_0pF,
461 _17_5pF,
463 _18_0pF,
465 _18_5pF,
467 _19_0pF,
469 _19_5pF,
471 _20_0pF,
473 }
474
475 #[cfg(feature = "nrf5340-app-s")]
476 impl HfxoCapacitance {
477 pub(crate) const fn value2(self) -> i32 {
479 match self {
480 HfxoCapacitance::_7_0pF => 14,
481 HfxoCapacitance::_7_5pF => 15,
482 HfxoCapacitance::_8_0pF => 16,
483 HfxoCapacitance::_8_5pF => 17,
484 HfxoCapacitance::_9_0pF => 18,
485 HfxoCapacitance::_9_5pF => 19,
486 HfxoCapacitance::_10_0pF => 20,
487 HfxoCapacitance::_10_5pF => 21,
488 HfxoCapacitance::_11_0pF => 22,
489 HfxoCapacitance::_11_5pF => 23,
490 HfxoCapacitance::_12_0pF => 24,
491 HfxoCapacitance::_12_5pF => 25,
492 HfxoCapacitance::_13_0pF => 26,
493 HfxoCapacitance::_13_5pF => 27,
494 HfxoCapacitance::_14_0pF => 28,
495 HfxoCapacitance::_14_5pF => 29,
496 HfxoCapacitance::_15_0pF => 30,
497 HfxoCapacitance::_15_5pF => 31,
498 HfxoCapacitance::_16_0pF => 32,
499 HfxoCapacitance::_16_5pF => 33,
500 HfxoCapacitance::_17_0pF => 34,
501 HfxoCapacitance::_17_5pF => 35,
502 HfxoCapacitance::_18_0pF => 36,
503 HfxoCapacitance::_18_5pF => 37,
504 HfxoCapacitance::_19_0pF => 38,
505 HfxoCapacitance::_19_5pF => 39,
506 HfxoCapacitance::_20_0pF => 40,
507 }
508 }
509 }
510
511 #[cfg(feature = "nrf5340-app-s")]
513 pub enum LfxoCapacitance {
514 _6pF = 1,
516 _7pF = 2,
518 _9pF = 3,
520 }
521
522 #[cfg(feature = "nrf5340-app-s")]
523 impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap {
524 fn from(t: LfxoCapacitance) -> Self {
525 match t {
526 LfxoCapacitance::_6pF => Self::C6PF,
527 LfxoCapacitance::_7pF => Self::C7PF,
528 LfxoCapacitance::_9pF => Self::C9PF,
529 }
530 }
531 }
532
533 #[non_exhaustive]
535 pub struct Config {
536 pub hfclk_source: HfclkSource,
538 pub lfclk_source: LfclkSource,
540 #[cfg(feature = "nrf5340-app-s")]
541 pub internal_capacitors: InternalCapacitors,
544 #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
545 pub dcdc: DcdcConfig,
547 #[cfg(feature = "gpiote")]
549 pub gpiote_interrupt_priority: crate::interrupt::Priority,
550 #[cfg(feature = "_time-driver")]
552 pub time_interrupt_priority: crate::interrupt::Priority,
553 pub debug: Debug,
555 }
556
557 impl Default for Config {
558 fn default() -> Self {
559 Self {
560 hfclk_source: HfclkSource::Internal,
564 lfclk_source: LfclkSource::InternalRC,
565 #[cfg(feature = "nrf5340-app-s")]
566 internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None },
567 #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
568 dcdc: DcdcConfig {
569 #[cfg(feature = "nrf52840")]
570 reg0: false,
571 #[cfg(any(feature = "nrf52840", feature = "nrf52833"))]
572 reg0_voltage: None,
573 reg1: false,
574 },
575 #[cfg(feature = "_nrf5340-app")]
576 dcdc: DcdcConfig {
577 regh: false,
578 #[cfg(feature = "nrf5340-app-s")]
579 regh_voltage: None,
580 regmain: false,
581 regradio: false,
582 },
583 #[cfg(feature = "_nrf91")]
584 dcdc: DcdcConfig { regmain: false },
585 #[cfg(feature = "gpiote")]
586 gpiote_interrupt_priority: crate::interrupt::Priority::P0,
587 #[cfg(feature = "_time-driver")]
588 time_interrupt_priority: crate::interrupt::Priority::P0,
589
590 #[cfg(feature = "_ns")]
592 debug: Debug::NotConfigured,
593 #[cfg(not(feature = "_ns"))]
594 debug: Debug::Allowed,
595 }
596 }
597 }
598}
599
600#[cfg(feature = "_nrf91")]
601#[allow(unused)]
602mod consts {
603 pub const UICR_APPROTECT: *mut u32 = 0x00FF8000 as *mut u32;
604 pub const UICR_HFXOSRC: *mut u32 = 0x00FF801C as *mut u32;
605 pub const UICR_HFXOCNT: *mut u32 = 0x00FF8020 as *mut u32;
606 pub const UICR_SECUREAPPROTECT: *mut u32 = 0x00FF802C as *mut u32;
607 pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
608 #[cfg(feature = "_nrf9120")]
609 pub const APPROTECT_DISABLED: u32 = 0x50FA50FA;
610}
611
612#[cfg(feature = "_nrf5340-app")]
613#[allow(unused)]
614mod consts {
615 pub const UICR_APPROTECT: *mut u32 = 0x00FF8000 as *mut u32;
616 pub const UICR_VREGHVOUT: *mut u32 = 0x00FF8010 as *mut u32;
617 pub const UICR_SECUREAPPROTECT: *mut u32 = 0x00FF801C as *mut u32;
618 pub const UICR_NFCPINS: *mut u32 = 0x00FF8028 as *mut u32;
619 pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
620 pub const APPROTECT_DISABLED: u32 = 0x50FA50FA;
621}
622
623#[cfg(feature = "_nrf5340-net")]
624#[allow(unused)]
625mod consts {
626 pub const UICR_APPROTECT: *mut u32 = 0x01FF8000 as *mut u32;
627 pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
628 pub const APPROTECT_DISABLED: u32 = 0x50FA50FA;
629}
630
631#[cfg(feature = "_nrf52")]
632#[allow(unused)]
633mod consts {
634 pub const UICR_PSELRESET1: *mut u32 = 0x10001200 as *mut u32;
635 pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32;
636 pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32;
637 pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32;
638 pub const UICR_REGOUT0: *mut u32 = 0x10001304 as *mut u32;
639 pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
640 pub const APPROTECT_DISABLED: u32 = 0x0000_005a;
641}
642
643#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
644#[derive(Debug, Copy, Clone, Eq, PartialEq)]
645#[cfg_attr(feature = "defmt", derive(defmt::Format))]
646enum WriteResult {
647 Written,
649 Noop,
651 Failed,
653}
654
655#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
656unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult {
657 uicr_write_masked(address, value, 0xFFFF_FFFF)
658}
659
660#[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))]
661unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult {
662 let curr_val = address.read_volatile();
663 if curr_val & mask == value & mask {
664 return WriteResult::Noop;
665 }
666
667 if curr_val & value & mask != value & mask {
669 return WriteResult::Failed;
670 }
671
672 cortex_m::interrupt::free(|_cs| {
674 let nvmc = pac::NVMC;
675
676 nvmc.config().write(|w| w.set_wen(pac::nvmc::vals::Wen::WEN));
677 while !nvmc.ready().read().ready() {}
678 address.write_volatile(value | !mask);
679 cortex_m::asm::dsb();
680 while !nvmc.ready().read().ready() {}
681 nvmc.config().write(|_| {});
682 while !nvmc.ready().read().ready() {}
683 });
684
685 WriteResult::Written
686}
687
688pub fn init(config: config::Config) -> Peripherals {
694 let peripherals = Peripherals::take();
697
698 #[allow(unused_mut)]
699 let mut needs_reset = false;
700
701 #[cfg(all(feature = "_nrf91", feature = "_s"))]
703 {
704 let uicr = pac::UICR_S;
705 let hfxocnt = uicr.hfxocnt().read().hfxocnt().to_bits();
706 let hfxosrc = uicr.hfxosrc().read().hfxosrc().to_bits();
707
708 if hfxosrc == 1 {
709 unsafe {
710 let _ = uicr_write(consts::UICR_HFXOSRC, 0);
711 }
712 needs_reset = true;
713 }
714
715 if hfxocnt == 255 {
716 unsafe {
717 let _ = uicr_write(consts::UICR_HFXOCNT, 32);
718 }
719 needs_reset = true;
720 }
721 }
722
723 #[cfg(all(feature = "_nrf54l", feature = "_s"))]
725 {
726 pac::GLITCHDET.config().write(|w| w.set_enable(false));
729 }
730
731 #[cfg(not(feature = "_nrf51"))]
733 match config.debug {
734 config::Debug::Allowed => {
735 #[cfg(feature = "_nrf52")]
736 unsafe {
737 let variant = (0x1000_0104 as *mut u32).read_volatile();
738 let build_code = (variant >> 8) as u8;
740
741 if build_code >= chip::APPROTECT_MIN_BUILD_CODE {
742 let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
749 needs_reset |= res == WriteResult::Written;
750 (0x4000_0558 as *mut u32).write_volatile(consts::APPROTECT_DISABLED);
752 } else {
753 }
755 }
756
757 #[cfg(feature = "_nrf5340")]
758 unsafe {
759 let p = pac::CTRLAP;
760
761 let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
762 needs_reset |= res == WriteResult::Written;
763 p.approtect().disable().write_value(consts::APPROTECT_DISABLED);
764
765 #[cfg(feature = "_nrf5340-app")]
766 {
767 let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_DISABLED);
768 needs_reset |= res == WriteResult::Written;
769 p.secureapprotect().disable().write_value(consts::APPROTECT_DISABLED);
770 }
771 }
772
773 #[cfg(all(feature = "_nrf54l", feature = "_s"))]
775 {
776 use crate::pac::tampc::vals;
777
778 let p = pac::TAMPC;
786
787 p.protect().domain(0).dbgen().ctrl().write(|w| {
789 w.set_key(vals::DomainDbgenCtrlKey::KEY);
790 w.set_writeprotection(vals::DomainDbgenCtrlWriteprotection::CLEAR);
791 });
792 p.protect().domain(0).dbgen().ctrl().write(|w| {
793 w.set_key(vals::DomainDbgenCtrlKey::KEY);
794 w.set_value(vals::DomainDbgenCtrlValue::HIGH);
795 });
796
797 p.protect().domain(0).niden().ctrl().write(|w| {
799 w.set_key(vals::NidenCtrlKey::KEY);
800 w.set_writeprotection(vals::NidenCtrlWriteprotection::CLEAR);
801 });
802 p.protect().domain(0).niden().ctrl().write(|w| {
803 w.set_key(vals::NidenCtrlKey::KEY);
804 w.set_value(vals::NidenCtrlValue::HIGH);
805 });
806
807 p.protect().domain(0).spiden().ctrl().write(|w| {
808 w.set_key(vals::SpidenCtrlKey::KEY);
809 w.set_writeprotection(vals::SpidenCtrlWriteprotection::CLEAR);
810 });
811 p.protect().domain(0).spiden().ctrl().write(|w| {
812 w.set_key(vals::SpidenCtrlKey::KEY);
813 w.set_value(vals::SpidenCtrlValue::HIGH);
814 });
815
816 p.protect().domain(0).spniden().ctrl().write(|w| {
817 w.set_key(vals::SpnidenCtrlKey::KEY);
818 w.set_writeprotection(vals::SpnidenCtrlWriteprotection::CLEAR);
819 });
820 p.protect().domain(0).spniden().ctrl().write(|w| {
821 w.set_key(vals::SpnidenCtrlKey::KEY);
822 w.set_value(vals::SpnidenCtrlValue::HIGH);
823 });
824 }
825
826 #[cfg(feature = "nrf9120-s")]
830 unsafe {
831 let p = pac::APPROTECT_S;
832
833 let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
834 needs_reset |= res == WriteResult::Written;
835 p.approtect()
836 .disable()
837 .write(|w| w.set_disable(pac::approtect::vals::ApprotectDisableDisable::SW_UNPROTECTED));
838
839 let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_DISABLED);
840 needs_reset |= res == WriteResult::Written;
841 p.secureapprotect()
842 .disable()
843 .write(|w| w.set_disable(pac::approtect::vals::SecureapprotectDisableDisable::SW_UNPROTECTED));
844
845 }
849 }
850 config::Debug::Disallowed => {
851 #[cfg(not(feature = "_nrf54l"))]
855 unsafe {
856 let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_ENABLED);
858 needs_reset |= res == WriteResult::Written;
859 #[cfg(any(feature = "_nrf5340-app", feature = "_nrf91"))]
860 {
861 let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_ENABLED);
862 needs_reset |= res == WriteResult::Written;
863 }
864
865 #[cfg(feature = "nrf9120-s")]
866 {
867 let p = pac::APPROTECT_S;
868 p.approtect().forceprotect().write(|w| w.set_forceprotect(true));
869 p.secureapprotect().forceprotect().write(|w| w.set_forceprotect(true));
870 }
871 }
872 }
873 config::Debug::NotConfigured => {}
874 }
875
876 #[cfg(feature = "_nrf52")]
877 unsafe {
878 let value = if cfg!(feature = "reset-pin-as-gpio") {
879 !0
880 } else {
881 chip::RESET_PIN
882 };
883 let res1 = uicr_write(consts::UICR_PSELRESET1, value);
884 let res2 = uicr_write(consts::UICR_PSELRESET2, value);
885 needs_reset |= res1 == WriteResult::Written || res2 == WriteResult::Written;
886 if res1 == WriteResult::Failed || res2 == WriteResult::Failed {
887 #[cfg(not(feature = "reset-pin-as-gpio"))]
888 warn!(
889 "You have requested enabling chip reset functionality on the reset pin, by not enabling the Cargo feature `reset-pin-as-gpio`.\n\
890 However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
891 To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
892 );
893 #[cfg(feature = "reset-pin-as-gpio")]
894 warn!(
895 "You have requested using the reset pin as GPIO, by enabling the Cargo feature `reset-pin-as-gpio`.\n\
896 However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
897 To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
898 );
899 }
900 }
901
902 #[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))]
903 unsafe {
904 let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 };
905 let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1);
906 needs_reset |= res == WriteResult::Written;
907 if res == WriteResult::Failed {
908 #[cfg(not(feature = "nfc-pins-as-gpio"))]
910 warn!(
911 "You have requested to use P0.09 and P0.10 pins for NFC, by not enabling the Cargo feature `nfc-pins-as-gpio`.\n\
912 However, UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
913 To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
914 );
915 }
916 }
917
918 #[cfg(any(feature = "nrf52840", feature = "nrf52833"))]
919 unsafe {
920 if let Some(value) = config.dcdc.reg0_voltage {
921 let value = value as u32;
922 let res = uicr_write_masked(consts::UICR_REGOUT0, value, 0b00000000_00000000_00000000_00000111);
923 needs_reset |= res == WriteResult::Written;
924 if res == WriteResult::Failed {
925 warn!(
926 "Failed to set regulator voltage, as UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
927 To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
928 );
929 }
930 }
931 }
932
933 #[cfg(feature = "nrf5340-app-s")]
934 unsafe {
935 if let Some(value) = config.dcdc.regh_voltage {
936 let value = value as u32;
937 let res = uicr_write_masked(consts::UICR_VREGHVOUT, value, 0b00000000_00000000_00000000_00000111);
938 needs_reset |= res == WriteResult::Written;
939 if res == WriteResult::Failed {
940 warn!(
941 "Failed to set regulator voltage, as UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
942 To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
943 );
944 }
945 }
946 }
947
948 if needs_reset {
949 cortex_m::peripheral::SCB::sys_reset();
950 }
951
952 #[cfg(feature = "nrf5340-app-s")]
954 {
955 if let Some(cap) = config.internal_capacitors.hfxo {
956 let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32;
957 let offset = pac::FICR.xosc32mtrim().read().offset() as i32;
958 if slope >= 16 {
960 slope -= 32;
961 }
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 }
968 if let Some(cap) = config.internal_capacitors.lfxo {
969 pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into()));
970 }
971 }
972
973 let r = pac::CLOCK;
974
975 match config.hfclk_source {
977 config::HfclkSource::Internal => {}
978 config::HfclkSource::ExternalXtal => {
979 #[cfg(feature = "_nrf54l")]
980 {
981 r.events_xostarted().write_value(0);
982 r.tasks_xostart().write_value(1);
983 while r.events_xostarted().read() == 0 {}
984 }
985
986 #[cfg(not(feature = "_nrf54l"))]
987 {
988 r.events_hfclkstarted().write_value(0);
990 r.tasks_hfclkstart().write_value(1);
991 while r.events_hfclkstarted().read() == 0 {}
992 }
993 }
994 }
995
996 #[cfg(feature = "nrf5340-app-s")]
998 if unsafe { (0x50032420 as *mut u32).read_volatile() } & 0x80000000 != 0 {
999 r.events_lfclkstarted().write_value(0);
1000 r.lfclksrc()
1001 .write(|w| w.set_src(nrf_pac::clock::vals::Lfclksrc::LFSYNT));
1002 r.tasks_lfclkstart().write_value(1);
1003 while r.events_lfclkstarted().read() == 0 {}
1004 r.events_lfclkstarted().write_value(0);
1005 r.tasks_lfclkstop().write_value(1);
1006 r.lfclksrc().write(|w| w.set_src(nrf_pac::clock::vals::Lfclksrc::LFRC));
1007 }
1008
1009 #[cfg(not(any(feature = "_nrf51", feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
1011 match config.lfclk_source {
1012 config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::RC)),
1013 config::LfclkSource::Synthesized => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::SYNTH)),
1014 config::LfclkSource::ExternalXtal => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::XTAL)),
1015 config::LfclkSource::ExternalLowSwing => r.lfclksrc().write(|w| {
1016 w.set_src(pac::clock::vals::Lfclksrc::XTAL);
1017 w.set_external(true);
1018 w.set_bypass(false);
1019 }),
1020 config::LfclkSource::ExternalFullSwing => r.lfclksrc().write(|w| {
1021 w.set_src(pac::clock::vals::Lfclksrc::XTAL);
1022 w.set_external(true);
1023 w.set_bypass(true);
1024 }),
1025 }
1026 #[cfg(feature = "_nrf5340")]
1027 {
1028 #[allow(unused_mut)]
1029 let mut lfxo = false;
1030 match config.lfclk_source {
1031 config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
1032 config::LfclkSource::Synthesized => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFSYNT)),
1033 #[cfg(not(feature = "lfxo-pins-as-gpio"))]
1034 config::LfclkSource::ExternalXtal => lfxo = true,
1035 #[cfg(not(feature = "lfxo-pins-as-gpio"))]
1036 config::LfclkSource::ExternalLowSwing => lfxo = true,
1037 #[cfg(not(feature = "lfxo-pins-as-gpio"))]
1038 config::LfclkSource::ExternalFullSwing => {
1039 #[cfg(feature = "_nrf5340-app")]
1040 pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true));
1041 lfxo = true;
1042 }
1043 }
1044 if lfxo {
1045 if cfg!(feature = "_s") {
1046 let p0 = pac::P0;
1048 p0.pin_cnf(0)
1049 .write(|w| w.set_mcusel(pac::gpio::vals::Mcusel::PERIPHERAL));
1050 p0.pin_cnf(1)
1051 .write(|w| w.set_mcusel(pac::gpio::vals::Mcusel::PERIPHERAL));
1052 }
1053 r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO));
1054 }
1055 }
1056 #[cfg(feature = "_nrf91")]
1057 match config.lfclk_source {
1058 config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
1059 config::LfclkSource::ExternalXtal => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO)),
1060 }
1061 #[cfg(feature = "_nrf54l")]
1062 match config.lfclk_source {
1063 config::LfclkSource::InternalRC => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
1064 config::LfclkSource::Synthesized => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFSYNT)),
1065 config::LfclkSource::ExternalXtal => r.lfclk().src().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO)),
1066 }
1067
1068 r.events_lfclkstarted().write_value(0);
1072 r.tasks_lfclkstart().write_value(1);
1073 while r.events_lfclkstarted().read() == 0 {}
1074
1075 #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
1076 {
1077 #[cfg(feature = "nrf52840")]
1079 if config.dcdc.reg0 {
1080 pac::POWER.dcdcen0().write(|w| w.set_dcdcen(true));
1081 }
1082 if config.dcdc.reg1 {
1083 pac::POWER.dcdcen().write(|w| w.set_dcdcen(true));
1084 }
1085 }
1086 #[cfg(feature = "_nrf91")]
1087 {
1088 if config.dcdc.regmain {
1090 pac::REGULATORS.dcdcen().write(|w| w.set_dcdcen(true));
1091 }
1092 }
1093 #[cfg(feature = "_nrf5340-app")]
1094 {
1095 let reg = pac::REGULATORS;
1097 if config.dcdc.regh {
1098 reg.vregh().dcdcen().write(|w| w.set_dcdcen(true));
1099 }
1100 if config.dcdc.regmain {
1101 reg.vregmain().dcdcen().write(|w| w.set_dcdcen(true));
1102 }
1103 if config.dcdc.regradio {
1104 reg.vregradio().dcdcen().write(|w| w.set_dcdcen(true));
1105 }
1106 }
1107 #[cfg(feature = "_nrf54l")]
1108 {
1109 pac::REGULATORS.vregmain().dcdcen().write(|w| w.set_val(true));
1115 }
1116
1117 #[cfg(not(feature = "_nrf54l"))] #[cfg(feature = "gpiote")]
1120 gpiote::init(config.gpiote_interrupt_priority);
1121
1122 #[cfg(feature = "_time-driver")]
1124 time_driver::init(config.time_interrupt_priority);
1125
1126 #[cfg(feature = "_nrf91")]
1128 {
1129 use pac::uarte::vals::Enable;
1130 pac::UARTE0.enable().write(|w| w.set_enable(Enable::DISABLED));
1131 pac::UARTE1.enable().write(|w| w.set_enable(Enable::DISABLED));
1132 }
1133
1134 peripherals
1135}
1136
1137pub mod mode {
1139 trait SealedMode {}
1140
1141 #[allow(private_bounds)]
1143 pub trait Mode: SealedMode {}
1144
1145 macro_rules! impl_mode {
1146 ($name:ident) => {
1147 impl SealedMode for $name {}
1148 impl Mode for $name {}
1149 };
1150 }
1151
1152 pub struct Blocking;
1154 pub struct Async;
1156
1157 impl_mode!(Blocking);
1158 impl_mode!(Async);
1159}