This is an automated email from the ASF dual-hosted git repository. janc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 711d7c57e9b32fe45714c05482706a2f500f9744 Author: Szymon Janc <[email protected]> AuthorDate: Wed Jun 7 16:06:54 2023 +0200 mcu/nrf5340: Add support for internal HFXO capacitors This allows to enable and trim internal load capacitors for 32 MHz crystal oscillator. --- hw/mcu/nordic/nrf5340/src/hal_system.c | 50 ++++++++++++++++++++++++++++++++++ hw/mcu/nordic/nrf5340/syscfg.yml | 8 ++++++ 2 files changed, 58 insertions(+) diff --git a/hw/mcu/nordic/nrf5340/src/hal_system.c b/hw/mcu/nordic/nrf5340/src/hal_system.c index 36868c0f9..a1e863f32 100644 --- a/hw/mcu/nordic/nrf5340/src/hal_system.c +++ b/hw/mcu/nordic/nrf5340/src/hal_system.c @@ -24,6 +24,8 @@ #include <hal/hal_debug.h> #include <nrf.h> #include <nrfx_config.h> +#include <hal/nrf_oscillators.h> +#include <tfm/tfm.h> /** * Function called at startup. Called after BSS and .data initialized but @@ -75,6 +77,49 @@ hal_debugger_connected(void) return CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; } +#if MYNEWT_VAL(MCU_HFXO_INTCAP) > 0 +static void +hfxo_int_cap_set(void) +{ + uint32_t xosc32mtrim; + uint32_t slope_field; + uint32_t slope_mask; + uint32_t slope_sign; + int32_t slope; + uint32_t offset; + uint32_t capvalue; + + if (tfm_ficr_xosc32mtrim_read(&xosc32mtrim) != 0) { + /* TODO assert? */ + return; + } + + /* The SLOPE field is in the two's complement form, hence this special + * handling. Ideally, it would result in just one SBFX instruction for + * extracting the slope value, at least gcc is capable of producing such + * output, but since the compiler apparently tries first to optimize + * additions and subtractions, it generates slightly less than optimal + * code. + */ + slope_field = (xosc32mtrim & FICR_XOSC32MTRIM_SLOPE_Msk) >> FICR_XOSC32MTRIM_SLOPE_Pos; + slope_mask = FICR_XOSC32MTRIM_SLOPE_Msk >> FICR_XOSC32MTRIM_SLOPE_Pos; + slope_sign = (slope_mask - (slope_mask >> 1)); + slope = (int32_t)(slope_field ^ slope_sign) - (int32_t)slope_sign; + offset = (xosc32mtrim & FICR_XOSC32MTRIM_OFFSET_Msk) >> FICR_XOSC32MTRIM_OFFSET_Pos; + + /* As specified in the nRF5340 PS: + * CAPVALUE = (((FICR->XOSC32MTRIM.SLOPE+56)*(CAPACITANCE*2-14)) + * +((FICR->XOSC32MTRIM.OFFSET-8)<<4)+32)>>6; + * where CAPACITANCE is the desired capacitor value in pF, holding any + * value between 7.0 pF and 20.0 pF in 0.5 pF steps. + */ + capvalue = ((slope + 56) * ((unsigned int)(MYNEWT_VAL(MCU_HFXO_INTCAP) * 2) - 14) + + ((offset - 8) << 4) + 32) >> 6; + + nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, true, capvalue); +} +#endif + /** * hal system clock start * @@ -152,6 +197,11 @@ hal_system_clock_start(void) } } #endif + +#if MYNEWT_VAL(MCU_HFXO_INTCAP) > 0 + hfxo_int_cap_set(); +#endif + if (MYNEWT_VAL(MCU_HFCLCK192_DIV) == 1) { NRF_CLOCK->HFCLK192MCTRL = 0; } else if (MYNEWT_VAL(MCU_HFCLCK192_DIV) == 2) { diff --git a/hw/mcu/nordic/nrf5340/syscfg.yml b/hw/mcu/nordic/nrf5340/syscfg.yml index 7314bc4ea..cfa8e4374 100644 --- a/hw/mcu/nordic/nrf5340/syscfg.yml +++ b/hw/mcu/nordic/nrf5340/syscfg.yml @@ -65,6 +65,14 @@ syscfg.defs: - c7pf # 7pF internal load capacitance - c9pf # 9pF internal load capacitance + MCU_HFXO_INTCAP: + description: > + Control usage of internal load capacitors for 32 MHz crystal + oscillator. Capacitors ranging from 7.0 pF to 20.0 pF in 0.5 pF + steps. Value 0 means external capacitors are used. + value: 0 + range: 0, 7..20 + MCU_GPIO_USE_PORT_EVENT: description: > When enabled, hal_gpio will use GPIOTE PORT event instead of PIN
