Skip to content

Commit 221d066

Browse files
ppryga-nordicanangl
authored andcommitted
[nrf fromlist] soc: nrf54l15: Fix LFXO INTCAP code calculations
There were two errors in calculations of LFXO INTCAP code: - The value provided by DTS files is internal desired capacitance. The value from DTS has to be "encoded" before use in INTCAP calculations formula. The formula for encoding is: CAPACITANCE_CODE = (<desired_value> - 4pF) / 0.5 Subtract of 4 is related with lowest value in the allowed range. Division by 0.5 is related with change to steps size. In former code the subtration of 4pF was missing. - The mid_val calcuation was wrong due offset_k left shift by 4. It should be left shift by 3 to get total left shift of 9. That matches the left shift of former part of the equation. Final integer value was calculated by right shift 10, it should be right shift 9. Then rounding was done by use of mod by (1 << 10) It should be mod by (1 << 9) and compared with (1 << 8), that is half of 0-512 range. Upstream PR: zephyrproject-rtos/zephyr#74668 Signed-off-by: Piotr Pryga <[email protected]>
1 parent 42f4e32 commit 221d066

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

soc/nordic/nrf54l/soc.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,34 @@ static int nordicsemi_nrf54l_init(void)
6565
* where CAPACITANCE is the desired capacitor value in pF, holding any
6666
* value between 4 pF and 18 pF in 0.5 pF steps.
6767
*/
68-
uint32_t mid_val =
69-
(((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) * 2UL) / 1000UL - 8UL) *
70-
(uint32_t)(slope_k + 392)) + (offset_k << 4UL);
71-
uint32_t capvalue_k = mid_val >> 10UL;
72-
73-
/* Round. */
74-
if ((mid_val % 1024UL) >= 512UL) {
75-
capvalue_k++;
68+
69+
/* Encoding of desired capacitance (single ended) to value required for INTCAP core
70+
* calculation: (CAP_VAL - 4 pF)* 0.5
71+
* That translate to ((CAP_VAL_FEMTO_F - 4000fF) * 2UL) / 1000UL
72+
*
73+
* NOTE: The desired capacitance value is used in encoded from in INTCAP calculation formula
74+
* That is different than in case of HFXO.
75+
*/
76+
uint32_t cap_val_encoded = (((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) - 4000UL)
77+
* 2UL) / 1000UL);
78+
79+
/* Calculation of INTCAP code before rounding. Min that calculations here are done on
80+
* values multiplied by 2^9, e.g. 0.765625 * 2^9 = 392.
81+
* offset_k should be divided by 2^6, but to add it to value shifted by 2^9 we have to
82+
* multiply it be 2^3.
83+
*/
84+
uint32_t mid_val = (cap_val_encoded - 4UL) * (uint32_t)(slope_k + 392UL)
85+
+ (offset_k << 3UL);
86+
87+
/* Get integer part of the INTCAP code */
88+
uint32_t lfxo_intcap = mid_val >> 9UL;
89+
90+
/* Round based on fractional part */
91+
if ((mid_val & BIT_MASK(9)) > (BIT_MASK(9) / 2)) {
92+
lfxo_intcap++;
7693
}
77-
nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)capvalue_k);
94+
95+
nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, lfxo_intcap);
7896
#elif DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, external)
7997
nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)0);
8098
#endif

0 commit comments

Comments
 (0)