Skip to content

Commit ec30e3e

Browse files
committed
nrf5340: add internal capacitor config
1 parent 17301c0 commit ec30e3e

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
@@ -360,13 +360,144 @@ pub mod config {
360360
pub regmain: bool,
361361
}
362362

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+
363490
/// Configuration for peripherals. Default configuration should work on any nRF chip.
364491
#[non_exhaustive]
365492
pub struct Config {
366493
/// High frequency clock source.
367494
pub hfclk_source: HfclkSource,
368495
/// Low frequency clock source.
369496
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,
370501
#[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
371502
/// DCDC configuration.
372503
pub dcdc: DcdcConfig,
@@ -388,6 +519,8 @@ pub mod config {
388519
// xtals if they know they have them.
389520
hfclk_source: HfclkSource::Internal,
390521
lfclk_source: LfclkSource::InternalRC,
522+
#[cfg(feature = "nrf5340-app-s")]
523+
internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None },
391524
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
392525
dcdc: DcdcConfig {
393526
#[cfg(feature = "nrf52840")]
@@ -687,6 +820,27 @@ pub fn init(config: config::Config) -> Peripherals {
687820
cortex_m::peripheral::SCB::sys_reset();
688821
}
689822

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+
690844
let r = pac::CLOCK;
691845

692846
// Start HFCLK.
@@ -753,7 +907,7 @@ pub fn init(config: config::Config) -> Peripherals {
753907
config::LfclkSource::ExternalLowSwing => lfxo = true,
754908
#[cfg(not(feature = "lfxo-pins-as-gpio"))]
755909
config::LfclkSource::ExternalFullSwing => {
756-
#[cfg(all(feature = "_nrf5340-app"))]
910+
#[cfg(feature = "_nrf5340-app")]
757911
pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true));
758912
lfxo = true;
759913
}

0 commit comments

Comments
 (0)