Skip to content

Commit 7650948

Browse files
authored
Merge pull request #3939 from 0e4ef622/nrf53-int-cap
nrf5340: add internal capacitor config
2 parents 75c1ca2 + ec30e3e commit 7650948

File tree

1 file changed

+155
-1
lines changed

1 file changed

+155
-1
lines changed

embassy-nrf/src/lib.rs

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,144 @@ pub mod config {
381381
pub regmain: bool,
382382
}
383383

384+
/// Settings for the internal capacitors.
385+
#[cfg(feature = "nrf5340-app-s")]
386+
pub struct InternalCapacitors {
387+
/// Config for the internal capacitors on pins XC1 and XC2.
388+
pub hfxo: Option<HfxoCapacitance>,
389+
/// Config for the internal capacitors between pins XL1 and XL2.
390+
pub lfxo: Option<LfxoCapacitance>,
391+
}
392+
393+
/// Internal capacitance value for the HFXO.
394+
#[cfg(feature = "nrf5340-app-s")]
395+
#[derive(Copy, Clone)]
396+
pub enum HfxoCapacitance {
397+
/// 7.0 pF
398+
_7_0pF,
399+
/// 7.5 pF
400+
_7_5pF,
401+
/// 8.0 pF
402+
_8_0pF,
403+
/// 8.5 pF
404+
_8_5pF,
405+
/// 9.0 pF
406+
_9_0pF,
407+
/// 9.5 pF
408+
_9_5pF,
409+
/// 10.0 pF
410+
_10_0pF,
411+
/// 10.5 pF
412+
_10_5pF,
413+
/// 11.0 pF
414+
_11_0pF,
415+
/// 11.5 pF
416+
_11_5pF,
417+
/// 12.0 pF
418+
_12_0pF,
419+
/// 12.5 pF
420+
_12_5pF,
421+
/// 13.0 pF
422+
_13_0pF,
423+
/// 13.5 pF
424+
_13_5pF,
425+
/// 14.0 pF
426+
_14_0pF,
427+
/// 14.5 pF
428+
_14_5pF,
429+
/// 15.0 pF
430+
_15_0pF,
431+
/// 15.5 pF
432+
_15_5pF,
433+
/// 16.0 pF
434+
_16_0pF,
435+
/// 16.5 pF
436+
_16_5pF,
437+
/// 17.0 pF
438+
_17_0pF,
439+
/// 17.5 pF
440+
_17_5pF,
441+
/// 18.0 pF
442+
_18_0pF,
443+
/// 18.5 pF
444+
_18_5pF,
445+
/// 19.0 pF
446+
_19_0pF,
447+
/// 19.5 pF
448+
_19_5pF,
449+
/// 20.0 pF
450+
_20_0pF,
451+
}
452+
453+
#[cfg(feature = "nrf5340-app-s")]
454+
impl HfxoCapacitance {
455+
/// The capacitance value times two.
456+
pub(crate) const fn value2(self) -> i32 {
457+
match self {
458+
HfxoCapacitance::_7_0pF => 14,
459+
HfxoCapacitance::_7_5pF => 15,
460+
HfxoCapacitance::_8_0pF => 16,
461+
HfxoCapacitance::_8_5pF => 17,
462+
HfxoCapacitance::_9_0pF => 18,
463+
HfxoCapacitance::_9_5pF => 19,
464+
HfxoCapacitance::_10_0pF => 20,
465+
HfxoCapacitance::_10_5pF => 21,
466+
HfxoCapacitance::_11_0pF => 22,
467+
HfxoCapacitance::_11_5pF => 23,
468+
HfxoCapacitance::_12_0pF => 24,
469+
HfxoCapacitance::_12_5pF => 25,
470+
HfxoCapacitance::_13_0pF => 26,
471+
HfxoCapacitance::_13_5pF => 27,
472+
HfxoCapacitance::_14_0pF => 28,
473+
HfxoCapacitance::_14_5pF => 29,
474+
HfxoCapacitance::_15_0pF => 30,
475+
HfxoCapacitance::_15_5pF => 31,
476+
HfxoCapacitance::_16_0pF => 32,
477+
HfxoCapacitance::_16_5pF => 33,
478+
HfxoCapacitance::_17_0pF => 34,
479+
HfxoCapacitance::_17_5pF => 35,
480+
HfxoCapacitance::_18_0pF => 36,
481+
HfxoCapacitance::_18_5pF => 37,
482+
HfxoCapacitance::_19_0pF => 38,
483+
HfxoCapacitance::_19_5pF => 39,
484+
HfxoCapacitance::_20_0pF => 40,
485+
}
486+
}
487+
}
488+
489+
/// Internal capacitance value for the LFXO.
490+
#[cfg(feature = "nrf5340-app-s")]
491+
pub enum LfxoCapacitance {
492+
/// 6 pF
493+
_6pF = 1,
494+
/// 7 pF
495+
_7pF = 2,
496+
/// 9 pF
497+
_9pF = 3,
498+
}
499+
500+
#[cfg(feature = "nrf5340-app-s")]
501+
impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap {
502+
fn from(t: LfxoCapacitance) -> Self {
503+
match t {
504+
LfxoCapacitance::_6pF => Self::C6PF,
505+
LfxoCapacitance::_7pF => Self::C7PF,
506+
LfxoCapacitance::_9pF => Self::C9PF,
507+
}
508+
}
509+
}
510+
384511
/// Configuration for peripherals. Default configuration should work on any nRF chip.
385512
#[non_exhaustive]
386513
pub struct Config {
387514
/// High frequency clock source.
388515
pub hfclk_source: HfclkSource,
389516
/// Low frequency clock source.
390517
pub lfclk_source: LfclkSource,
518+
#[cfg(feature = "nrf5340-app-s")]
519+
/// Internal capacitor configuration, for use with the `ExternalXtal` clock source. See
520+
/// nrf5340-PS §4.12.
521+
pub internal_capacitors: InternalCapacitors,
391522
#[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
392523
/// DCDC configuration.
393524
pub dcdc: DcdcConfig,
@@ -409,6 +540,8 @@ pub mod config {
409540
// xtals if they know they have them.
410541
hfclk_source: HfclkSource::Internal,
411542
lfclk_source: LfclkSource::InternalRC,
543+
#[cfg(feature = "nrf5340-app-s")]
544+
internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None },
412545
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
413546
dcdc: DcdcConfig {
414547
#[cfg(feature = "nrf52840")]
@@ -726,6 +859,27 @@ pub fn init(config: config::Config) -> Peripherals {
726859
cortex_m::peripheral::SCB::sys_reset();
727860
}
728861

862+
// Configure internal capacitors
863+
#[cfg(feature = "nrf5340-app-s")]
864+
{
865+
if let Some(cap) = config.internal_capacitors.hfxo {
866+
let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32;
867+
let offset = pac::FICR.xosc32mtrim().read().offset() as i32;
868+
// slope is a signed 5-bit integer
869+
if slope >= 16 {
870+
slope -= 32;
871+
}
872+
let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6;
873+
pac::OSCILLATORS.xosc32mcaps().write(|w| {
874+
w.set_capvalue(capvalue as u8);
875+
w.set_enable(true);
876+
});
877+
}
878+
if let Some(cap) = config.internal_capacitors.lfxo {
879+
pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into()));
880+
}
881+
}
882+
729883
let r = pac::CLOCK;
730884

731885
// Start HFCLK.
@@ -792,7 +946,7 @@ pub fn init(config: config::Config) -> Peripherals {
792946
config::LfclkSource::ExternalLowSwing => lfxo = true,
793947
#[cfg(not(feature = "lfxo-pins-as-gpio"))]
794948
config::LfclkSource::ExternalFullSwing => {
795-
#[cfg(all(feature = "_nrf5340-app"))]
949+
#[cfg(feature = "_nrf5340-app")]
796950
pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true));
797951
lfxo = true;
798952
}

0 commit comments

Comments
 (0)