Skip to content

Commit

Permalink
nrf5340: add internal capacitor config
Browse files Browse the repository at this point in the history
  • Loading branch information
0e4ef622 committed Mar 2, 2025
1 parent 17301c0 commit c23218b
Showing 1 changed file with 155 additions and 1 deletion.
156 changes: 155 additions & 1 deletion embassy-nrf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,13 +360,144 @@ pub mod config {
pub regmain: bool,
}

/// Settings for the internal capacitors.
#[cfg(feature = "_nrf5340-app")]
pub struct InternalCapacitors {
/// Config for the internal capacitors on pins XC1 and XC2.
pub hfxo: Option<HfxoCapacitance>,
/// Config for the internal capacitors between pins XL1 and XL2.
pub lfxo: Option<LfxoCapacitance>,
}

/// Internal capacitance value for the HFXO.
#[cfg(feature = "_nrf5340-app")]
#[derive(Copy, Clone)]
pub enum HfxoCapacitance {
/// 7.0 pF
_7_0pF,
/// 7.5 pF
_7_5pF,
/// 8.0 pF
_8_0pF,
/// 8.5 pF
_8_5pF,
/// 9.0 pF
_9_0pF,
/// 9.5 pF
_9_5pF,
/// 10.0 pF
_10_0pF,
/// 10.5 pF
_10_5pF,
/// 11.0 pF
_11_0pF,
/// 11.5 pF
_11_5pF,
/// 12.0 pF
_12_0pF,
/// 12.5 pF
_12_5pF,
/// 13.0 pF
_13_0pF,
/// 13.5 pF
_13_5pF,
/// 14.0 pF
_14_0pF,
/// 14.5 pF
_14_5pF,
/// 15.0 pF
_15_0pF,
/// 15.5 pF
_15_5pF,
/// 16.0 pF
_16_0pF,
/// 16.5 pF
_16_5pF,
/// 17.0 pF
_17_0pF,
/// 17.5 pF
_17_5pF,
/// 18.0 pF
_18_0pF,
/// 18.5 pF
_18_5pF,
/// 19.0 pF
_19_0pF,
/// 19.5 pF
_19_5pF,
/// 20.0 pF
_20_0pF,
}

#[cfg(feature = "_nrf5340-app")]
impl HfxoCapacitance {
/// The capacitance value times two.
pub(crate) const fn value2(self) -> i32 {
match self {
HfxoCapacitance::_7_0pF => 14,
HfxoCapacitance::_7_5pF => 15,
HfxoCapacitance::_8_0pF => 16,
HfxoCapacitance::_8_5pF => 17,
HfxoCapacitance::_9_0pF => 18,
HfxoCapacitance::_9_5pF => 19,
HfxoCapacitance::_10_0pF => 20,
HfxoCapacitance::_10_5pF => 21,
HfxoCapacitance::_11_0pF => 22,
HfxoCapacitance::_11_5pF => 23,
HfxoCapacitance::_12_0pF => 24,
HfxoCapacitance::_12_5pF => 25,
HfxoCapacitance::_13_0pF => 26,
HfxoCapacitance::_13_5pF => 27,
HfxoCapacitance::_14_0pF => 28,
HfxoCapacitance::_14_5pF => 29,
HfxoCapacitance::_15_0pF => 30,
HfxoCapacitance::_15_5pF => 31,
HfxoCapacitance::_16_0pF => 32,
HfxoCapacitance::_16_5pF => 33,
HfxoCapacitance::_17_0pF => 34,
HfxoCapacitance::_17_5pF => 35,
HfxoCapacitance::_18_0pF => 36,
HfxoCapacitance::_18_5pF => 37,
HfxoCapacitance::_19_0pF => 38,
HfxoCapacitance::_19_5pF => 39,
HfxoCapacitance::_20_0pF => 40,
}
}
}

/// Internal capacitance value for the LFXO.
#[cfg(feature = "_nrf5340-app")]
pub enum LfxoCapacitance {
/// 6 pF
_6pF = 1,
/// 7 pF
_7pF = 2,
/// 9 pF
_9pF = 3,
}

#[cfg(feature = "_nrf5340-app")]
impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap {
fn from(t: LfxoCapacitance) -> Self {
match t {
LfxoCapacitance::_6pF => Self::C6PF,
LfxoCapacitance::_7pF => Self::C7PF,
LfxoCapacitance::_9pF => Self::C9PF,
}
}
}

/// Configuration for peripherals. Default configuration should work on any nRF chip.
#[non_exhaustive]
pub struct Config {
/// High frequency clock source.
pub hfclk_source: HfclkSource,
/// Low frequency clock source.
pub lfclk_source: LfclkSource,
#[cfg(feature = "_nrf5340-app")]
/// Internal capacitor configuration, for use with the `ExternalXtal` clock source. See
/// nrf5340-PS §4.12.
pub internal_capacitors: InternalCapacitors,
#[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))]
/// DCDC configuration.
pub dcdc: DcdcConfig,
Expand All @@ -388,6 +519,8 @@ pub mod config {
// xtals if they know they have them.
hfclk_source: HfclkSource::Internal,
lfclk_source: LfclkSource::InternalRC,
#[cfg(feature = "_nrf5340-app")]
internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None },
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
dcdc: DcdcConfig {
#[cfg(feature = "nrf52840")]
Expand Down Expand Up @@ -687,6 +820,27 @@ pub fn init(config: config::Config) -> Peripherals {
cortex_m::peripheral::SCB::sys_reset();
}

// Configure internal capacitors
#[cfg(feature = "_nrf5340-app")]
{
if let Some(cap) = config.internal_capacitors.hfxo {
let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32;
let offset = pac::FICR.xosc32mtrim().read().offset() as i32;
// slope is a signed 5-bit integer
if slope >= 16 {
slope -= 32;
}
let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6;
pac::OSCILLATORS.xosc32mcaps().write(|w| {
w.set_capvalue(capvalue as u8);
w.set_enable(true);
});
}
if let Some(cap) = config.internal_capacitors.lfxo {
pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into()));
}
}

let r = pac::CLOCK;

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

0 comments on commit c23218b

Please sign in to comment.