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. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
e0f8a8f16e
commit
f0f5f28f99
1 changed files with 26 additions and 8 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue