nRF54LM20A LFXO: Datasheet INTCAP formula vs NRF_OSCILLATORS_LFXO_CAP_CALCULATE macro give very different results

Hi,

I’m working on nRF54LM20A and trying to configure the internal capacitors for the 32.768 kHz crystal (LFXO) using the factory trim values in FICR.

According to the nRF54LM20A Product Specification, the LFXO internal capacitor value (INTCAP) should be calculated with the following formula (section “Low-frequency (32.768 kHz) crystal oscillator (LFXO)”):

INTCAP = round( (2*CAPACITANCE - 12) * (FICR->XOSC32KTRIM.SLOPE + 0.765625 * 512)/512 + FICR->XOSC32KTRIM.OFFSET/64 ) [LFXO formula]

On my chip, the FICR values are:

  • FICR->XOSC32KTRIM.SLOPE = 6
  • FICR->XOSC32KTRIM.OFFSET = 302

For a target capacitance of 18 pF, plugging into the datasheet formula gives:

  • 2 * CAPACITANCE - 12 = 24
  • SLOPE + 0.765625 * 512 = 6 + 392 = 398
  • (SLOPE + 0.765625 * 512)/512 = 398/512 ≈ 0.77734375
  • Main term: 24 * 0.77734375 ≈ 18.65625
  • Offset term: OFFSET/64 = 302/64 = 4.71875
  • Sum: 18.65625 + 4.71875 = 23.375
  • INTCAP ≈ round(23.375) = 23

So from the Product Spec formula, 18 pF ⇒ INTCAP ≈ 23.

However, in nrfx there is the LFXO capacitance macro:

#define NRF_OSCILLATORS_LFXO_CAP_CALCULATE(p_ficr_reg, cap_val)                      \
      (((((p_ficr_reg->XOSC32KTRIM & FICR_XOSC32KTRIM_SLOPE_Msk)                     \
        >> FICR_XOSC32KTRIM_SLOPE_Pos) + 392) >> 9) * (uint32_t)(cap_val * 2 - 12) + \
       (((p_ficr_reg->XOSC32KTRIM & FICR_XOSC32KTRIM_OFFSET_Msk)                     \
        >> FICR_XOSC32KTRIM_OFFSET_Pos) >> 6))

(from NRF_OSCILLATORS_LFXO_CAP_CALCULATE in nrfx HAL). [LFXO macro]

Using this macro:

uint32_t lfxo_cap_cfg = NRF_OSCILLATORS_LFXO_CAP_CALCULATE(NRF_FICR, 18);

With SLOPE = 6 and OFFSET = 302, the calculation becomes:

  • (SLOPE + 392) = 398
  • (SLOPE + 392) >> 9 = 398 >> 9 = 0 // because 398 < 512
  • cap_val * 2 - 12 = 18 * 2 - 12 = 24
  • Main term: 0 * 24 = 0
  • Offset term: OFFSET >> 6 = 302 >> 6 = 4
  • Result: lfxo_cap_cfg = 4

So for 18 pF, the macro returns 4, which is very far from the ~23 suggested by the Product Specification formula.

The same happens if I try 5 pF:

uint32_t lfxo_cap_cfg = NRF_OSCILLATORS_LFXO_CAP_CALCULATE(NRF_FICR, 5);

Result is also 4, due to (SLOPE + 392) >> 9 becoming 0, so the term that depends on cap_val effectively disappears for my SLOPE value.

My questions:

  1. For nRF54LM20A, which is the intended way to configure the LFXO internal capacitors?

    • Should we follow the Product Specification formula directly and write the resulting INTCAP value (e.g. ~23 for 18 pF) into OSCILLATORS.XOSC32KI.INTCAP? [XOSC32KI.INTCAP]
    • Or should we use the NRF_OSCILLATORS_LFXO_CAP_CALCULATE macro and accept the much smaller encoded value (e.g. 4 in this case)?
  2. Is the current NRF_OSCILLATORS_LFXO_CAP_CALCULATE macro fully aligned with the nRF54LM20A Product Specification, or is there a known issue/limitation with certain SLOPE/OFFSET combinations (like SLOPE=6) where the quantization becomes too coarse?

  3. Is there any recommended method from Nordic to:

    • verify that the resulting INTCAP value is correct (for example via a measurement or test mode), and
    • choose the best INTCAP for a given LFXO load capacitance on nRF54LM20A?

Right now I see a big discrepancy between the floating‑point formula in the spec (18 pF → ~23) and the integer macro in nrfx (18 pF → 4) for my particular chip, and I’d like to understand which value is actually correct to use, and whether the macro is intended for nRF54LM20A as-is.

Thanks in advance for any clarification.

Parents Reply Children
No Data
Related