diff --git a/soc/nordic/nrf54l/soc.c b/soc/nordic/nrf54l/soc.c index 94f48c14233..4054a963449 100644 --- a/soc/nordic/nrf54l/soc.c +++ b/soc/nordic/nrf54l/soc.c @@ -65,16 +65,34 @@ static int nordicsemi_nrf54l_init(void) * where CAPACITANCE is the desired capacitor value in pF, holding any * value between 4 pF and 18 pF in 0.5 pF steps. */ - uint32_t mid_val = - (((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) * 2UL) / 1000UL - 8UL) * - (uint32_t)(slope_k + 392)) + (offset_k << 4UL); - uint32_t capvalue_k = mid_val >> 10UL; - /* Round. */ - if ((mid_val % 1024UL) >= 512UL) { - capvalue_k++; + /* Encoding of desired capacitance (single ended) to value required for INTCAP core + * calculation: (CAP_VAL - 4 pF)* 0.5 + * That translate to ((CAP_VAL_FEMTO_F - 4000fF) * 2UL) / 1000UL + * + * NOTE: The desired capacitance value is used in encoded from in INTCAP calculation formula + * That is different than in case of HFXO. + */ + uint32_t cap_val_encoded = (((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) - 4000UL) + * 2UL) / 1000UL); + + /* Calculation of INTCAP code before rounding. Min that calculations here are done on + * values multiplied by 2^9, e.g. 0.765625 * 2^9 = 392. + * offset_k should be divided by 2^6, but to add it to value shifted by 2^9 we have to + * multiply it be 2^3. + */ + uint32_t mid_val = (cap_val_encoded - 4UL) * (uint32_t)(slope_k + 392UL) + + (offset_k << 3UL); + + /* Get integer part of the INTCAP code */ + uint32_t lfxo_intcap = mid_val >> 9UL; + + /* Round based on fractional part */ + if ((mid_val & BIT_MASK(9)) > (BIT_MASK(9) / 2)) { + lfxo_intcap++; } - nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)capvalue_k); + + nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, lfxo_intcap); #elif DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, external) nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)0); #endif