Skip to content

Commit cc0c00f

Browse files
ppryga-nordicanangl
authored andcommitted
[nrf fromlist] soc: nrf54l15: Fix HFXO INTCAP code calculation rounding error
The implementation of formula, to calculate HFXO INTCAP code, had a rounding error. That may lead so small deviation of HFXO clock accuracy. The IPS formula uses capacitance values in piko Fartd units. That requires use of floating point data types. To avoid that implementation of the formula uses femto Farats (1000 smaller unit). In the former implementation conversion from femto Farad to piko Farad was done just after reading of the desired capacitance from DTS. To make sure the calculations are correct the change of unit must be done at very end. Also rounding must be applied. Also the formula was split and more comments were added to make the implementation clear. The commit fixes the implementation of the IPS formula. Upstream PR: zephyrproject-rtos/zephyr#74668 Signed-off-by: Piotr Pryga <[email protected]>
1 parent 221d066 commit cc0c00f

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

soc/nordic/nrf54l/soc.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,28 @@ static int nordicsemi_nrf54l_init(void)
119119
* where CAPACITANCE is the desired total load capacitance value in pF,
120120
* holding any value between 4.0 pF and 17.0 pF in 0.25 pF steps.
121121
*/
122-
uint32_t capvalue =
123-
(((((DT_PROP(HFXO_NODE, load_capacitance_femtofarad) * 4UL) / 1000UL) - 22UL) *
124-
(uint32_t)(slope_m + 791) / 4UL) + (offset_m << 2UL)) >> 8UL;
125122

126-
nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, true, capvalue);
123+
/* NOTE 1: Requested HFXO internal capacitance in femto Faradas is used directly in formula
124+
* to calculate INTCAP code. That is different than in case of LFXO.
125+
*
126+
* NOTE 2: PS formula uses piko Farads, the implementation of the formula uses femto Farads
127+
* to avoid use of floating point data type.
128+
*/
129+
uint32_t cap_val_femto_f = DT_PROP(HFXO_NODE, load_capacitance_femtofarad);
130+
131+
uint32_t mid_val_intcap = (((cap_val_femto_f - 5500UL) * (uint32_t)(slope_m + 791UL))
132+
+ (offset_m << 2UL) * 1000UL) >> 8UL;
133+
134+
/* Convert the calculated value to piko Farads */
135+
uint32_t hfxo_intcap = mid_val_intcap / 1000;
136+
137+
/* Round based on fractional part */
138+
if (mid_val_intcap % 1000 >= 500) {
139+
hfxo_intcap++;
140+
}
141+
142+
nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, true, hfxo_intcap);
143+
127144
#elif DT_ENUM_HAS_VALUE(HFXO_NODE, load_capacitors, external)
128145
nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, false, 0);
129146
#endif

0 commit comments

Comments
 (0)