aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
authorMatthew Tran <[email protected]>2025-03-01 23:01:06 -0600
committerMatthew Tran <[email protected]>2025-03-02 00:06:41 -0600
commitec30e3ef91f0dfa9983990c710ad3a4574847634 (patch)
tree9cf918d31cfcf70ab0027bcb197e462caf98fcc2 /embassy-nrf
parent17301c00e986c5b8536435ea31ebf5aaf13aed17 (diff)
nrf5340: add internal capacitor config
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/lib.rs156
1 files changed, 155 insertions, 1 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 23888b390..f2cf0d77e 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -360,6 +360,133 @@ pub mod config {
360 pub regmain: bool, 360 pub regmain: bool,
361 } 361 }
362 362
363 /// Settings for the internal capacitors.
364 #[cfg(feature = "nrf5340-app-s")]
365 pub struct InternalCapacitors {
366 /// Config for the internal capacitors on pins XC1 and XC2.
367 pub hfxo: Option<HfxoCapacitance>,
368 /// Config for the internal capacitors between pins XL1 and XL2.
369 pub lfxo: Option<LfxoCapacitance>,
370 }
371
372 /// Internal capacitance value for the HFXO.
373 #[cfg(feature = "nrf5340-app-s")]
374 #[derive(Copy, Clone)]
375 pub enum HfxoCapacitance {
376 /// 7.0 pF
377 _7_0pF,
378 /// 7.5 pF
379 _7_5pF,
380 /// 8.0 pF
381 _8_0pF,
382 /// 8.5 pF
383 _8_5pF,
384 /// 9.0 pF
385 _9_0pF,
386 /// 9.5 pF
387 _9_5pF,
388 /// 10.0 pF
389 _10_0pF,
390 /// 10.5 pF
391 _10_5pF,
392 /// 11.0 pF
393 _11_0pF,
394 /// 11.5 pF
395 _11_5pF,
396 /// 12.0 pF
397 _12_0pF,
398 /// 12.5 pF
399 _12_5pF,
400 /// 13.0 pF
401 _13_0pF,
402 /// 13.5 pF
403 _13_5pF,
404 /// 14.0 pF
405 _14_0pF,
406 /// 14.5 pF
407 _14_5pF,
408 /// 15.0 pF
409 _15_0pF,
410 /// 15.5 pF
411 _15_5pF,
412 /// 16.0 pF
413 _16_0pF,
414 /// 16.5 pF
415 _16_5pF,
416 /// 17.0 pF
417 _17_0pF,
418 /// 17.5 pF
419 _17_5pF,
420 /// 18.0 pF
421 _18_0pF,
422 /// 18.5 pF
423 _18_5pF,
424 /// 19.0 pF
425 _19_0pF,
426 /// 19.5 pF
427 _19_5pF,
428 /// 20.0 pF
429 _20_0pF,
430 }
431
432 #[cfg(feature = "nrf5340-app-s")]
433 impl HfxoCapacitance {
434 /// The capacitance value times two.
435 pub(crate) const fn value2(self) -> i32 {
436 match self {
437 HfxoCapacitance::_7_0pF => 14,
438 HfxoCapacitance::_7_5pF => 15,
439 HfxoCapacitance::_8_0pF => 16,
440 HfxoCapacitance::_8_5pF => 17,
441 HfxoCapacitance::_9_0pF => 18,
442 HfxoCapacitance::_9_5pF => 19,
443 HfxoCapacitance::_10_0pF => 20,
444 HfxoCapacitance::_10_5pF => 21,
445 HfxoCapacitance::_11_0pF => 22,
446 HfxoCapacitance::_11_5pF => 23,
447 HfxoCapacitance::_12_0pF => 24,
448 HfxoCapacitance::_12_5pF => 25,
449 HfxoCapacitance::_13_0pF => 26,
450 HfxoCapacitance::_13_5pF => 27,
451 HfxoCapacitance::_14_0pF => 28,
452 HfxoCapacitance::_14_5pF => 29,
453 HfxoCapacitance::_15_0pF => 30,
454 HfxoCapacitance::_15_5pF => 31,
455 HfxoCapacitance::_16_0pF => 32,
456 HfxoCapacitance::_16_5pF => 33,
457 HfxoCapacitance::_17_0pF => 34,
458 HfxoCapacitance::_17_5pF => 35,
459 HfxoCapacitance::_18_0pF => 36,
460 HfxoCapacitance::_18_5pF => 37,
461 HfxoCapacitance::_19_0pF => 38,
462 HfxoCapacitance::_19_5pF => 39,
463 HfxoCapacitance::_20_0pF => 40,
464 }
465 }
466 }
467
468 /// Internal capacitance value for the LFXO.
469 #[cfg(feature = "nrf5340-app-s")]
470 pub enum LfxoCapacitance {
471 /// 6 pF
472 _6pF = 1,
473 /// 7 pF
474 _7pF = 2,
475 /// 9 pF
476 _9pF = 3,
477 }
478
479 #[cfg(feature = "nrf5340-app-s")]
480 impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap {
481 fn from(t: LfxoCapacitance) -> Self {
482 match t {
483 LfxoCapacitance::_6pF => Self::C6PF,
484 LfxoCapacitance::_7pF => Self::C7PF,
485 LfxoCapacitance::_9pF => Self::C9PF,
486 }
487 }
488 }
489
363 /// Configuration for peripherals. Default configuration should work on any nRF chip. 490 /// Configuration for peripherals. Default configuration should work on any nRF chip.
364 #[non_exhaustive] 491 #[non_exhaustive]
365 pub struct Config { 492 pub struct Config {
@@ -367,6 +494,10 @@ pub mod config {
367 pub hfclk_source: HfclkSource, 494 pub hfclk_source: HfclkSource,
368 /// Low frequency clock source. 495 /// Low frequency clock source.
369 pub lfclk_source: LfclkSource, 496 pub lfclk_source: LfclkSource,
497 #[cfg(feature = "nrf5340-app-s")]
498 /// Internal capacitor configuration, for use with the `ExternalXtal` clock source. See
499 /// nrf5340-PS ยง4.12.
500 pub internal_capacitors: InternalCapacitors,
370 #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))] 501 #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
371 /// DCDC configuration. 502 /// DCDC configuration.
372 pub dcdc: DcdcConfig, 503 pub dcdc: DcdcConfig,
@@ -388,6 +519,8 @@ pub mod config {
388 // xtals if they know they have them. 519 // xtals if they know they have them.
389 hfclk_source: HfclkSource::Internal, 520 hfclk_source: HfclkSource::Internal,
390 lfclk_source: LfclkSource::InternalRC, 521 lfclk_source: LfclkSource::InternalRC,
522 #[cfg(feature = "nrf5340-app-s")]
523 internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None },
391 #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))] 524 #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
392 dcdc: DcdcConfig { 525 dcdc: DcdcConfig {
393 #[cfg(feature = "nrf52840")] 526 #[cfg(feature = "nrf52840")]
@@ -687,6 +820,27 @@ pub fn init(config: config::Config) -> Peripherals {
687 cortex_m::peripheral::SCB::sys_reset(); 820 cortex_m::peripheral::SCB::sys_reset();
688 } 821 }
689 822
823 // Configure internal capacitors
824 #[cfg(feature = "nrf5340-app-s")]
825 {
826 if let Some(cap) = config.internal_capacitors.hfxo {
827 let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32;
828 let offset = pac::FICR.xosc32mtrim().read().offset() as i32;
829 // slope is a signed 5-bit integer
830 if slope >= 16 {
831 slope -= 32;
832 }
833 let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6;
834 pac::OSCILLATORS.xosc32mcaps().write(|w| {
835 w.set_capvalue(capvalue as u8);
836 w.set_enable(true);
837 });
838 }
839 if let Some(cap) = config.internal_capacitors.lfxo {
840 pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into()));
841 }
842 }
843
690 let r = pac::CLOCK; 844 let r = pac::CLOCK;
691 845
692 // Start HFCLK. 846 // Start HFCLK.
@@ -753,7 +907,7 @@ pub fn init(config: config::Config) -> Peripherals {
753 config::LfclkSource::ExternalLowSwing => lfxo = true, 907 config::LfclkSource::ExternalLowSwing => lfxo = true,
754 #[cfg(not(feature = "lfxo-pins-as-gpio"))] 908 #[cfg(not(feature = "lfxo-pins-as-gpio"))]
755 config::LfclkSource::ExternalFullSwing => { 909 config::LfclkSource::ExternalFullSwing => {
756 #[cfg(all(feature = "_nrf5340-app"))] 910 #[cfg(feature = "_nrf5340-app")]
757 pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true)); 911 pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true));
758 lfxo = true; 912 lfxo = true;
759 } 913 }