From 5f2b136ae442a4b589b5d72f73f354c26c9f63c2 Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Thu, 24 Oct 2024 22:28:18 -0700 Subject: [PATCH 1/6] da1469x/clock: Add missing services This commit adds the missing services to the driver API. It also makes the actual calibration of the XTAL32K clock a syscfg option, defaulting to 0. --- .../da1469x/include/mcu/da1469x_clock.h | 40 +++++++++++ hw/mcu/dialog/da1469x/src/da1469x_clock.c | 71 ++++++++++++++++++- hw/mcu/dialog/da1469x/syscfg.yml | 5 ++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h index ceec050949..861c9d5c16 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -61,6 +61,21 @@ void da1469x_clock_sys_xtal32m_switch_safe(void); */ void da1469x_clock_sys_rc32m_disable(void); +/** + * Enable RC32M + */ +void da1469x_clock_sys_rc32m_enable(void); + +/** + * Switch sys_clk to RC32M + */ +void da1469x_clock_sys_rc32m_switch(void); + +/** + * Disable XTAL32K + */ +void da1469x_clock_lp_xtal32k_disable(void); + /** * Enable XTAL32K */ @@ -73,6 +88,21 @@ void da1469x_clock_lp_xtal32k_enable(void); */ void da1469x_clock_lp_xtal32k_switch(void); +/** + * Disable RC32K + */ +void da1469x_clock_lp_rc32k_disable(void); + +/** + * Enable RC32K + */ +void da1469x_clock_lp_rc32k_enable(void); + +/** + * Switch lp_clk to RC32K + */ +void da1469x_clock_lp_rc32k_switch(void); + /** * Enable RCX */ @@ -95,6 +125,11 @@ void da1469x_clock_lp_rcx_calibrate(void); */ void da1469x_clock_lp_rc32k_calibrate(void); +/** + * Calibrate XTAL32K + */ +void da1469x_clock_lp_xtal32k_calibrate(void); + /** * Calibrate RC32M */ @@ -110,6 +145,11 @@ uint32_t da1469x_clock_lp_rcx_freq_get(void); */ uint32_t da1469x_clock_lp_rc32k_freq_get(void); +/** + * Get calibrated XTAL32K frequency + */ +uint32_t da1469x_clock_lp_xtal32k_freq_get(void); + /** * Get calibrated (measured) RC32M frequency */ diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 114023f24f..59bf6a87fd 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -34,7 +34,8 @@ static uint32_t g_mcu_clock_rcx_freq; static uint32_t g_mcu_clock_rc32k_freq; -static uint32_t g_mcu_clock_rc32m_freq; +static uint32_t g_mcu_clock_rc32m_freq = RC32M_FREQ; +static uint32_t g_mcu_clock_xtal32k_freq; uint32_t SystemCoreClock = RC32M_FREQ; @@ -129,6 +130,30 @@ da1469x_clock_sys_rc32m_disable(void) CRG_TOP->CLK_RC32M_REG &= ~CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk; } +void +da1469x_clock_sys_rc32m_enable(void) +{ + CRG_TOP->CLK_RC32M_REG |= CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk; +} + +void +da1469x_clock_sys_rc32m_switch(void) +{ + CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & + ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk) | + (1 << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos); + + while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk)); + + SystemCoreClock = g_mcu_clock_rc32m_freq; +} + +void +da1469x_clock_lp_xtal32k_disable(void) +{ + CRG_TOP->CLK_XTAL32K_REG &= ~CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk; +} + void da1469x_clock_lp_xtal32k_enable(void) { @@ -147,6 +172,31 @@ da1469x_clock_lp_xtal32k_switch(void) } } +void +da1469x_clock_lp_rc32k_disable(void) +{ + CRG_TOP->CLK_RC32K_REG &= ~CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk; +} + +void +da1469x_clock_lp_rc32k_enable(void) +{ + CRG_TOP->CLK_RC32K_REG |= CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk; +} + +void +da1469x_clock_lp_rc32k_switch(void) +{ + CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & + ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | + (0 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); + + /* If system is running on LP clock update SystemCoreClock */ + if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk) { + SystemCoreClock = g_mcu_clock_rc32k_freq; + } +} + void da1469x_clock_lp_rcx_enable(void) { @@ -286,6 +336,17 @@ da1469x_clock_lp_rc32k_calibrate(void) g_mcu_clock_rc32k_freq = freq; } +void +da1469x_clock_lp_xtal32k_calibrate(void) +{ +#if MYNEWT_VAL(MCU_CLOCK_XTAL32K_ALLOW_CALIB) + g_mcu_clock_xtal32k_freq = + da1469x_clock_calibrate(2, MYNEWT_VAL(MCU_CLOCK_RCX_CAL_REF_CNT)); +#else + g_mcu_clock_xtal32k_freq = XTAL32K_FREQ; +#endif +} + void da1469x_clock_lp_rc32m_calibrate(void) { @@ -308,6 +369,14 @@ da1469x_clock_lp_rc32k_freq_get(void) return g_mcu_clock_rc32k_freq; } +uint32_t +da1469x_clock_lp_xtal32k_freq_get(void) +{ + assert(g_mcu_clock_xtal32k_freq); + + return g_mcu_clock_xtal32k_freq; +} + uint32_t da1469x_clock_lp_rc32m_freq_get(void) { diff --git a/hw/mcu/dialog/da1469x/syscfg.yml b/hw/mcu/dialog/da1469x/syscfg.yml index 5e808b69bc..cf781e8329 100644 --- a/hw/mcu/dialog/da1469x/syscfg.yml +++ b/hw/mcu/dialog/da1469x/syscfg.yml @@ -67,6 +67,11 @@ syscfg.defs: Specifies settling time [ms] of 32K crystal oscillator. value: 8000 + MCU_CLOCK_XTAL32K_ALLOW_CALIB: + description: > + Specifies that the 32K crystal oscillator should be calibrated. + value: 0 + MCU_CLOCK_RCX_CAL_REF_CNT: description: > Reference count value for calibration of RCX clock. The higher From e818ba1b30da2ee2a0defafff19fa2f40227f8ad Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Fri, 25 Oct 2024 01:50:03 -0700 Subject: [PATCH 2/6] da1469x/clock: Eliminate magic numbers This commit replaces the magic numbers with meaningfully named constants. --- .../da1469x/include/mcu/da1469x_clock.h | 4 +- hw/mcu/dialog/da1469x/src/da1469x_clock.c | 113 +++++++++++++----- hw/mcu/dialog/da1469x/syscfg.yml | 12 ++ 3 files changed, 95 insertions(+), 34 deletions(-) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h index 861c9d5c16..91689d197d 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -133,7 +133,7 @@ void da1469x_clock_lp_xtal32k_calibrate(void); /** * Calibrate RC32M */ -void da1469x_clock_lp_rc32m_calibrate(void); +void da1469x_clock_sys_rc32m_calibrate(void); /** * Get calibrated (measured) RCX frequency @@ -153,7 +153,7 @@ uint32_t da1469x_clock_lp_xtal32k_freq_get(void); /** * Get calibrated (measured) RC32M frequency */ -uint32_t da1469x_clock_lp_rc32m_freq_get(void); +uint32_t da1469x_clock_sys_rc32m_freq_get(void); /** * Disable RCX diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 59bf6a87fd..ba9a8e7130 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -29,8 +29,53 @@ #define XTAL32M_FREQ 32000000 #define RC32M_FREQ 32000000 +#define RC32M_FREQ_MIN 30600000 +#define RC32M_FREQ_MAX 32600000 +#define DIVN_FREQ 32000000 /* For CLK_CTRL_REG::SYS_CLK_SEL != 2 (LP clock) */ +#define CAL_REF_FREQ DIVN_FREQ /* For CLK_REF_SEL_REG::CAL_CLK_SEL = 0 (DivN) */ #define PLL_FREQ 96000000 #define XTAL32K_FREQ 32768 +#define XTALRDY_IRQ_FREQ 256000 /* For XTALRDY_CTRL_REG::XTALRDY_CLK_SEL = 1 (256 kHz) */ + +#define XTALRDY_IRQ_DIV (RC32M_FREQ / XTALRDY_IRQ_FREQ) +#define XTALRDY_IRQ_FREQ_MAX (RC32M_FREQ_MAX / XTALRDY_IRQ_DIV) + +enum da1469x_sys_clk_sel { + DA1469X_SYS_XTAL32M = 0, + DA1469X_SYS_RC32M, + DA1469X_SYS_LP_CLK, + DA1469X_SYS_PLL96M, +}; + +enum da1469x_xtalrdy_clk_sel { + DA1469X_XTALRDY_CLK_32K = 0, + DA1469X_XTALRDY_CLK_256K, +}; +#define DA1469X_XTALRDY_CLK_SEL DA1469X_XTALRDY_CLK_256K + +enum da1469x_lp_clk_sel { + DA1469X_LP_RC32K = 0, + DA1469X_LP_RCX, + DA1469X_LP_XTAL32K, + DA1469X_LP_EXT, +}; + +enum da1469x_ref_sel { + DA1469X_REF_DIVN = 0, + DA1469X_REF_RC32M, + DA1469X_REF_RC32K, + DA1469X_REF_XTAL32K, + DA1469X_REF_RCOSC, +}; +#define DA1469X_REF_SEL DA1469X_REF_DIVN + +enum da1469x_calib_sel { + DA1469X_CALIB_RC32K = 0, + DA1469X_CALIB_RC32M, + DA1469X_CALIB_XTAL32K, + DA1469X_CALIB_RCX, + DA1469X_CALIB_RCOSC, +}; static uint32_t g_mcu_clock_rcx_freq; static uint32_t g_mcu_clock_rc32k_freq; @@ -42,27 +87,23 @@ uint32_t SystemCoreClock = RC32M_FREQ; static inline bool da1469x_clock_is_xtal32m_settled(void) { - return ((*(uint32_t *)0x5001001c & 0xff00) == 0) && - ((*(uint32_t *)0x50010054 & 0x000f) != 0xb); + return ((CRG_XTAL->XTALRDY_STAT_REG & CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_COUNT_Msk) == 0) && + ((CRG_XTAL->XTAL32M_STAT1_REG & CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_STATE_Msk) != 0xb); } void da1469x_clock_sys_xtal32m_init(void) { - uint32_t reg; int xtalrdy_cnt; /* - * Number of 256kHz clock cycles (~4.085us) assuming worst case when actual frequency is 244800. - * RC32M is in range <30.6, 32.6> so 256Khz can ba as low as 30.6MHz / 125 = 244.8kHz. + * Number of XTALRDY IRQ timer clock cycles making up the desired xtal settling time, + * sufficient even at maximum RC32M frequency. */ - xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 1000 / 4085; + xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * XTALRDY_IRQ_FREQ_MAX / 1000000; - reg = CRG_XTAL->XTALRDY_CTRL_REG; - reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk); - reg |= CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk; - reg |= xtalrdy_cnt; - CRG_XTAL->XTALRDY_CTRL_REG = reg; + CRG_XTAL->XTALRDY_CTRL_REG = (xtalrdy_cnt << CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Pos) | + (DA1469X_XTALRDY_CLK_SEL << CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Pos); } void @@ -88,7 +129,9 @@ da1469x_clock_sys_xtal32m_switch(void) if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) { CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk; } else { - CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; + CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & + ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk) | + (DA1469X_SYS_XTAL32M << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos); } while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk)); @@ -141,7 +184,7 @@ da1469x_clock_sys_rc32m_switch(void) { CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk) | - (1 << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos); + (DA1469X_SYS_RC32M << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos); while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk)); @@ -165,7 +208,7 @@ da1469x_clock_lp_xtal32k_switch(void) { CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | - (2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); + (DA1469X_LP_XTAL32K << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); /* If system is running on LP clock update SystemCoreClock */ if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk) { SystemCoreClock = XTAL32K_FREQ; @@ -189,7 +232,7 @@ da1469x_clock_lp_rc32k_switch(void) { CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | - (0 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); + (DA1469X_LP_RC32K << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); /* If system is running on LP clock update SystemCoreClock */ if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk) { @@ -208,7 +251,7 @@ da1469x_clock_lp_rcx_switch(void) { CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | - (1 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); + (DA1469X_LP_RCX << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); /* If system is running on LP clock update SystemCoreClock */ if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk) { @@ -238,23 +281,30 @@ da1469x_clock_calibrate(uint8_t clock_sel, uint16_t ref_cnt) assert(!(ANAMISC_BIF->CLK_REF_SEL_REG & ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk)); ANAMISC_BIF->CLK_REF_CNT_REG = ref_cnt; - ANAMISC_BIF->CLK_REF_SEL_REG = (clock_sel << ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos) | - ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk; + /* Select reference clock & calibrated clock */ + ANAMISC_BIF->CLK_REF_SEL_REG = + (DA1469X_REF_SEL << ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Pos) | + (clock_sel << ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos); + + /* Start measurement */ + ANAMISC_BIF->CLK_REF_SEL_REG |= ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk; + + /* Wait for meaurement to complete */ while (ANAMISC_BIF->CLK_REF_SEL_REG & ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk); ref_val = ANAMISC_BIF->CLK_REF_VAL_REG; da1469x_pd_release(MCU_PD_DOMAIN_PER); - return 32000000 * ref_cnt / ref_val; + return CAL_REF_FREQ * ref_cnt / ref_val; } void da1469x_clock_lp_rcx_calibrate(void) { g_mcu_clock_rcx_freq = - da1469x_clock_calibrate(3, MYNEWT_VAL(MCU_CLOCK_RCX_CAL_REF_CNT)); + da1469x_clock_calibrate(DA1469X_CALIB_RCX, MYNEWT_VAL(MCU_CLOCK_RCX_CAL_REF_CNT)); } #define RC32K_TARGET_FREQ 32000 @@ -302,7 +352,7 @@ da1469x_clock_lp_rc32k_calibrate(void) freq_prev = freq; freq_delta_prev = freq_delta; - freq = da1469x_clock_calibrate(0, MYNEWT_VAL(MCU_CLOCK_RC32K_CAL_REF_CNT)); + freq = da1469x_clock_calibrate(DA1469X_CALIB_RC32K, MYNEWT_VAL(MCU_CLOCK_RC32K_CAL_REF_CNT)); freq_delta = freq - RC32K_TARGET_FREQ; freq_delta = (int32_t)freq_delta < 0 ? -freq_delta : freq_delta; @@ -341,16 +391,17 @@ da1469x_clock_lp_xtal32k_calibrate(void) { #if MYNEWT_VAL(MCU_CLOCK_XTAL32K_ALLOW_CALIB) g_mcu_clock_xtal32k_freq = - da1469x_clock_calibrate(2, MYNEWT_VAL(MCU_CLOCK_RCX_CAL_REF_CNT)); + da1469x_clock_calibrate(DA1469X_CALIB_XTAL32K, MYNEWT_VAL(MCU_CLOCK_XTAL32K_CAL_REF_CNT)); #else g_mcu_clock_xtal32k_freq = XTAL32K_FREQ; #endif } void -da1469x_clock_lp_rc32m_calibrate(void) +da1469x_clock_sys_rc32m_calibrate(void) { - g_mcu_clock_rc32m_freq = da1469x_clock_calibrate(1, 100); + g_mcu_clock_rc32m_freq = da1469x_clock_calibrate(DA1469X_CALIB_RC32M, + MYNEWT_VAL(MCU_CLOCK_RC32M_CAL_REF_CNT)); } uint32_t @@ -378,7 +429,7 @@ da1469x_clock_lp_xtal32k_freq_get(void) } uint32_t -da1469x_clock_lp_rc32m_freq_get(void) +da1469x_clock_sys_rc32m_freq_get(void) { assert(g_mcu_clock_rc32m_freq); @@ -394,11 +445,8 @@ da1469x_clock_lp_rcx_disable(void) static void da1469x_delay_us(uint32_t delay_us) { - /* - * SysTick runs on ~32 MHz clock while PLL is not started. - * so multiplying by 32 to convert from us to SysTicks. - */ - SysTick->LOAD = delay_us * 32; + /* Convert from us to SysTicks (PLL is not started yet) */ + SysTick->LOAD = delay_us * XTAL32M_FREQ / 1000000; SysTick->VAL = 0UL; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; while (0 == (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); @@ -483,8 +531,9 @@ da1469x_clock_pll_wait_to_lock(void) void da1469x_clock_sys_pll_switch(void) { - /* CLK_SEL_Msk == 3 means PLL */ - CRG_TOP->CLK_CTRL_REG |= CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; + CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & + ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk) | + (DA1469X_SYS_PLL96M << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos); while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk)); diff --git a/hw/mcu/dialog/da1469x/syscfg.yml b/hw/mcu/dialog/da1469x/syscfg.yml index cf781e8329..1c62e7064a 100644 --- a/hw/mcu/dialog/da1469x/syscfg.yml +++ b/hw/mcu/dialog/da1469x/syscfg.yml @@ -88,6 +88,18 @@ syscfg.defs: value: 1 restrictions: '!0' + MCU_CLOCK_XTAL32K_CAL_REF_CNT: + description: > + Reference count value for calibration of XTAL32K clock. + value: 100 + restrictions: '!0' + + MCU_CLOCK_RC32M_CAL_REF_CNT: + description: > + Reference count value for calibration of RC32M clock. + value: 100 + restrictions: '!0' + MCU_SYSCLK_SOURCE: description: > Specifies system clock source From b80af1633718eb59434e704a8089ff5b20cb12e6 Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Fri, 25 Oct 2024 02:17:58 -0700 Subject: [PATCH 3/6] da1469x/clock: Streamline the LP clock API This commit streamlines the LP clock API, by offering clean access to the LP clock selected via sysconfig. --- .../da1469x/include/mcu/da1469x_clock.h | 10 +++++ .../da1469x/include/mcu/da1469x_lpclk.h | 3 ++ hw/mcu/dialog/da1469x/src/da1469x_clock.c | 24 ++++++++++ hw/mcu/dialog/da1469x/src/da1469x_lpclk.c | 44 +++++++++++++++---- hw/mcu/dialog/da1469x/src/hal_system.c | 19 +------- 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h index 91689d197d..8906dca737 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -130,6 +130,11 @@ void da1469x_clock_lp_rc32k_calibrate(void); */ void da1469x_clock_lp_xtal32k_calibrate(void); +/** + * Calibrate selected LP clock + */ +void da1469x_clock_lp_calibrate(void); + /** * Calibrate RC32M */ @@ -150,6 +155,11 @@ uint32_t da1469x_clock_lp_rc32k_freq_get(void); */ uint32_t da1469x_clock_lp_xtal32k_freq_get(void); +/** + * Get seleted LP clock's frequency + */ +uint32_t da1469x_clock_lp_freq_get(void); + /** * Get calibrated (measured) RC32M frequency */ diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h index 5f0ace4fc5..27b75d1d25 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h @@ -33,6 +33,9 @@ void da1469x_lpclk_register_cmac_cb(da1469x_lpclk_cb *cb); void da1469x_lpclk_enabled(void); /* Frequency of lp clock changed (e.g. after RCX recalibration) */ void da1469x_lpclk_updated(void); +/* Initialize selected LP RC clock */ +void da1469x_lpclk_rc_init(); + #ifdef __cplusplus } diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index ba9a8e7130..47d02d8e01 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -397,6 +397,18 @@ da1469x_clock_lp_xtal32k_calibrate(void) #endif } +void +da1469x_clock_lp_calibrate(void) +{ +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + da1469x_clock_lp_rcx_calibrate(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RC32K) + da1469x_clock_lp_rc32k_calibrate(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) + da1469x_clock_lp_xtal32k_calibrate(); +#endif +} + void da1469x_clock_sys_rc32m_calibrate(void) { @@ -428,6 +440,18 @@ da1469x_clock_lp_xtal32k_freq_get(void) return g_mcu_clock_xtal32k_freq; } +uint32_t +da1469x_clock_lp_freq_get(void) +{ +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + return da1469x_clock_lp_rcx_freq_get(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RC32K) + return da1469x_clock_lp_rc32k_freq_get(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) + return da1469x_clock_lp_xtal32k_freq_get(); +#endif +} + uint32_t da1469x_clock_sys_rc32m_freq_get(void) { diff --git a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c index 3b603cbf5a..e39c3af9fe 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c @@ -32,6 +32,7 @@ bool g_mcu_lpclk_available; static da1469x_lpclk_cb *g_da1469x_lpclk_cmac_cb; +static uint32_t g_lpclk_last_freq = 0; #if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) static void @@ -45,15 +46,17 @@ da1469x_lpclk_settle_tmr_cb(void *arg) static void da1469x_lpclk_notify(void) { - if (!g_da1469x_lpclk_cmac_cb || !g_mcu_lpclk_available) { - return; - } + uint32_t lp_curr_freq; -#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) - g_da1469x_lpclk_cmac_cb(32768); -#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) - g_da1469x_lpclk_cmac_cb(da1469x_clock_lp_rcx_freq_get()); -#endif + lp_curr_freq = da1469x_clock_lp_freq_get(); + + if (lp_curr_freq != g_lpclk_last_freq) { + g_lpclk_last_freq = lp_curr_freq; + + if (g_da1469x_lpclk_cmac_cb && g_mcu_lpclk_available) { + g_da1469x_lpclk_cmac_cb(lp_curr_freq); + } + } } void @@ -76,6 +79,31 @@ da1469x_lpclk_updated(void) da1469x_lpclk_notify(); } +void +da1469x_lpclk_rc_init(void) +{ +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + da1469x_clock_lp_rc32k_disable(); + da1469x_clock_lp_rcx_enable(); + da1469x_clock_lp_rcx_switch(); + da1469x_clock_lp_calibrate(); + da1469x_lpclk_enabled(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RC32K) + da1469x_clock_lp_rcx_disable(); + da1469x_clock_lp_rc32k_enable(); + da1469x_clock_lp_rc32k_switch(); + da1469x_clock_lp_calibrate(); + da1469x_lpclk_enabled(); +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) + /* + * We cannot switch lp_clk to XTAL32K here since it needs some time to + * settle, so we just disable RCX (we don't need it) and then we'll handle + * switch to XTAL32K from sysinit since we need os_cputime for this. + */ + da1469x_clock_lp_rcx_disable(); +#endif +} + void da1469x_lpclk_init(void) { diff --git a/hw/mcu/dialog/da1469x/src/hal_system.c b/hw/mcu/dialog/da1469x/src/hal_system.c index 0a503915d4..d326e26ef8 100644 --- a/hw/mcu/dialog/da1469x/src/hal_system.c +++ b/hw/mcu/dialog/da1469x/src/hal_system.c @@ -125,23 +125,8 @@ hal_system_clock_start(void) #endif da1469x_clock_sys_rc32m_disable(); -#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) - /* Switch to RCX and calibrate it */ - da1469x_clock_lp_rcx_enable(); - da1469x_clock_lp_rcx_switch(); - da1469x_clock_lp_rcx_calibrate(); - da1469x_lpclk_enabled(); -#else - /* - * We cannot switch lp_clk to XTAL32K here since it needs some time to - * settle, so we just disable RCX (we don't need it) and then we'll handle - * switch to XTAL32K from sysinit since we need os_cputime for this. - */ - da1469x_clock_lp_rcx_disable(); -#endif - - /* TODO: we should calibrate this periodically */ - da1469x_clock_lp_rc32k_calibrate(); + /* Initialize the selected RC LP clock */ + da1469x_lpclk_rc_init(); } enum hal_reset_reason From 914f3f7f61a6c189b1d4e5cf989d796f90634ca3 Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Fri, 25 Oct 2024 02:36:47 -0700 Subject: [PATCH 4/6] da1469x/clock: Calculate the RTC dividers This commit adds the function that calculates the RTC divider registers, and invokes it when the LP clock frequency changes. --- .../da1469x/include/mcu/da1469x_clock.h | 5 ++++ hw/mcu/dialog/da1469x/src/da1469x_clock.c | 24 +++++++++++++++++++ hw/mcu/dialog/da1469x/src/da1469x_lpclk.c | 2 ++ 3 files changed, 31 insertions(+) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h index 8906dca737..8c44d40dce 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -170,6 +170,11 @@ uint32_t da1469x_clock_sys_rc32m_freq_get(void); */ void da1469x_clock_lp_rcx_disable(void); +/** + * Set the RTC dividers + */ +void da1469x_clock_lp_set_rtc_divs(void); + /** * Enable AMBA clock(s) * diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 47d02d8e01..0d7dc5178a 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -40,6 +40,9 @@ #define XTALRDY_IRQ_DIV (RC32M_FREQ / XTALRDY_IRQ_FREQ) #define XTALRDY_IRQ_FREQ_MAX (RC32M_FREQ_MAX / XTALRDY_IRQ_DIV) +#define RTC_IN_FREQ_HZ 100 +#define RTC_DIV_FRAC_ADJ 10 /* For CLK_RTCDIV_REG::RTC_DIV_DENOM = 0 (1000) */ + enum da1469x_sys_clk_sel { DA1469X_SYS_XTAL32M = 0, DA1469X_SYS_RC32M, @@ -77,6 +80,12 @@ enum da1469x_calib_sel { DA1469X_CALIB_RCOSC, }; +enum da1469x_rtc_div_denom_sel { + DA1469X_RTC_DIV_DENOM_1000 = 0, + DA1469X_RTC_DIV_DENOM_1024, +}; +#define DA1469X_RTC_DIV_DENOM_SEL DA1469X_RTC_DIV_DENOM_1000 + static uint32_t g_mcu_clock_rcx_freq; static uint32_t g_mcu_clock_rc32k_freq; static uint32_t g_mcu_clock_rc32m_freq = RC32M_FREQ; @@ -466,6 +475,21 @@ da1469x_clock_lp_rcx_disable(void) CRG_TOP->CLK_RCX_REG &= ~CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk; } +void +da1469x_clock_lp_set_rtc_divs(void) +{ + /* Please see the DA1469x desig doc section 2.20.4 for details */ + uint32_t reg; + + reg = ((da1469x_clock_lp_freq_get() % RTC_IN_FREQ_HZ) * RTC_DIV_FRAC_ADJ) << + CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Pos; + reg |= ((da1469x_clock_lp_freq_get() / RTC_IN_FREQ_HZ)) << + CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Pos; + reg |= DA1469X_RTC_DIV_DENOM_SEL << CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Pos; + reg |= CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk; + CRG_TOP->CLK_RTCDIV_REG = reg; +} + static void da1469x_delay_us(uint32_t delay_us) { diff --git a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c index e39c3af9fe..169875c3e8 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c @@ -56,6 +56,8 @@ da1469x_lpclk_notify(void) if (g_da1469x_lpclk_cmac_cb && g_mcu_lpclk_available) { g_da1469x_lpclk_cmac_cb(lp_curr_freq); } + + da1469x_clock_lp_set_rtc_divs(); } } From 217eeb1f0e78fedd2412cba65a675fc7a94cd61b Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Fri, 25 Oct 2024 14:16:03 -0700 Subject: [PATCH 5/6] da1469x/os-tick: Fix slightly incorrect time-keeping If the LP clock's frequency is not an integer multiple of the specified OS tick frequency, the period of OS ticks will be incorrect due to an integer division truncation error (to the tune of almost 1% for RCX), resulting in OS Time gradually creeping away from the actual time. This commit fixes the issue, by maintaining the fractional OS tick value and advance OS Time accordingly. --- .../da1469x/include/mcu/da1469x_clock.h | 2 +- .../dialog/da1469x/include/mcu/da1469x_hal.h | 7 +++ hw/mcu/dialog/da1469x/src/da1469x_clock.c | 8 +-- hw/mcu/dialog/da1469x/src/da1469x_lpclk.c | 3 +- hw/mcu/dialog/da1469x/src/hal_os_tick.c | 57 ++++++++++++------- 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h index 8c44d40dce..cf2e78008a 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h @@ -173,7 +173,7 @@ void da1469x_clock_lp_rcx_disable(void); /** * Set the RTC dividers */ -void da1469x_clock_lp_set_rtc_divs(void); +void da1469x_clock_lp_set_rtc_divs(uint32_t rtc_clock_freq); /** * Enable AMBA clock(s) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h index 78e1675289..2d0a17dc79 100755 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h @@ -87,6 +87,13 @@ extern const int qspi_flash_config_array_size; const struct qspi_flash_config *da1469x_qspi_get_config(void); +/** + * Calculate the OS tick parameters. + * + * @param cycles_per_sec Input frequency of timer generating OS ticks + */ +void hal_os_tick_calc_params(uint32_t cycles_per_sec); + #ifdef __cplusplus } #endif diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 0d7dc5178a..3e15980906 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -476,14 +476,14 @@ da1469x_clock_lp_rcx_disable(void) } void -da1469x_clock_lp_set_rtc_divs(void) +da1469x_clock_lp_set_rtc_divs(uint32_t rtc_clock_freq) { - /* Please see the DA1469x desig doc section 2.20.4 for details */ + /* Please see the DA1469x Datasheet section 34.3 for details */ uint32_t reg; - reg = ((da1469x_clock_lp_freq_get() % RTC_IN_FREQ_HZ) * RTC_DIV_FRAC_ADJ) << + reg = ((rtc_clock_freq % RTC_IN_FREQ_HZ) * RTC_DIV_FRAC_ADJ) << CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Pos; - reg |= ((da1469x_clock_lp_freq_get() / RTC_IN_FREQ_HZ)) << + reg |= ((rtc_clock_freq / RTC_IN_FREQ_HZ)) << CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Pos; reg |= DA1469X_RTC_DIV_DENOM_SEL << CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Pos; reg |= CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk; diff --git a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c index 169875c3e8..7cb3173b8c 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c @@ -57,7 +57,8 @@ da1469x_lpclk_notify(void) g_da1469x_lpclk_cmac_cb(lp_curr_freq); } - da1469x_clock_lp_set_rtc_divs(); + da1469x_clock_lp_set_rtc_divs(lp_curr_freq); + hal_os_tick_calc_params(lp_curr_freq); } } diff --git a/hw/mcu/dialog/da1469x/src/hal_os_tick.c b/hw/mcu/dialog/da1469x/src/hal_os_tick.c index 64bc53653b..0673f4399d 100644 --- a/hw/mcu/dialog/da1469x/src/hal_os_tick.c +++ b/hw/mcu/dialog/da1469x/src/hal_os_tick.c @@ -28,7 +28,10 @@ #include "mcu/mcu.h" struct hal_os_tick { - int ticks_per_ostick; + uint32_t os_ticks_per_sec; /* Configured upon init */ + uint32_t cycles_per_ostick; /* For generating the OS ticks */ + uint32_t cycles_per_256_osticks; /* For more precise OS Time calculation */ + uint32_t os_tick_residual; os_time_t max_idle_ticks; uint32_t last_trigger_val; }; @@ -88,7 +91,7 @@ hal_os_tick_set_timer_trigger_val(uint32_t trigger_val) break; } - trigger_val += g_hal_os_tick.ticks_per_ostick; + trigger_val += g_hal_os_tick.cycles_per_ostick; } } @@ -97,28 +100,28 @@ hal_os_tick_handler(void) { uint32_t primask; uint32_t timer_val; - int delta; - int ticks; + uint32_t delta_x256; + uint32_t ticks; __HAL_DISABLE_INTERRUPTS(primask); - /* Calculate elapsed ticks and advance OS time. */ + /* Calculate elapsed cycles of timer & record its current value */ timer_val = hal_os_tick_get_timer_val(); - delta = sub24(timer_val, g_hal_os_tick.last_trigger_val); - ticks = delta / g_hal_os_tick.ticks_per_ostick; - os_time_advance(ticks); + delta_x256 = ((timer_val - g_hal_os_tick.last_trigger_val) & 0xffffff) << 8; + g_hal_os_tick.last_trigger_val = timer_val; /* Clear timer interrupt */ TIMER2->TIMER2_CLEAR_IRQ_REG = 1; - /* Update the time associated with the most recent tick */ - g_hal_os_tick.last_trigger_val = (g_hal_os_tick.last_trigger_val + - (ticks * g_hal_os_tick.ticks_per_ostick)) & - 0xffffff; + /* Re-arm timer for the next OS tick */ + hal_os_tick_set_timer_trigger_val(timer_val + g_hal_os_tick.cycles_per_ostick); - /* Update timer trigger value for interrupt at the next tick */ - hal_os_tick_set_timer_trigger_val(g_hal_os_tick.last_trigger_val + - g_hal_os_tick.ticks_per_ostick); + /* Update OS Time */ + ticks = delta_x256 / g_hal_os_tick.cycles_per_256_osticks; + g_hal_os_tick.os_tick_residual += delta_x256 % g_hal_os_tick.cycles_per_256_osticks; + ticks += g_hal_os_tick.os_tick_residual / g_hal_os_tick.cycles_per_256_osticks; + g_hal_os_tick.os_tick_residual %= g_hal_os_tick.cycles_per_256_osticks; + os_time_advance(ticks); __HAL_ENABLE_INTERRUPTS(primask); } @@ -133,6 +136,19 @@ hal_os_tick_timer2_isr(void) os_trace_isr_exit(); } +void +hal_os_tick_calc_params(uint32_t cycles_per_sec) +{ + /* Upon imit, `os_ticks_per_sec` becomes available only after clock setup - skip for now */ + if (g_hal_os_tick.os_ticks_per_sec == 0) { + return; + } + + g_hal_os_tick.cycles_per_256_osticks = (cycles_per_sec << 8) / g_hal_os_tick.os_ticks_per_sec; + g_hal_os_tick.cycles_per_ostick = g_hal_os_tick.cycles_per_256_osticks >> 8; + g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.cycles_per_ostick; +} + void os_tick_idle(os_time_t ticks) { @@ -146,7 +162,7 @@ os_tick_idle(os_time_t ticks) } new_trigger_val = g_hal_os_tick.last_trigger_val + - (ticks * g_hal_os_tick.ticks_per_ostick); + (ticks * g_hal_os_tick.cycles_per_ostick); hal_os_tick_set_timer_trigger_val(new_trigger_val); } @@ -163,13 +179,10 @@ os_tick_init(uint32_t os_ticks_per_sec, int prio) { uint32_t primask; + g_hal_os_tick.os_ticks_per_sec = os_ticks_per_sec; g_hal_os_tick.last_trigger_val = 0; -#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) - g_hal_os_tick.ticks_per_ostick = da1469x_clock_lp_rcx_freq_get() / os_ticks_per_sec; -#else - g_hal_os_tick.ticks_per_ostick = 32768 / os_ticks_per_sec; -#endif - g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick; + g_hal_os_tick.os_tick_residual = 0; + hal_os_tick_calc_params(da1469x_clock_lp_freq_get()); TIMER2->TIMER2_CTRL_REG = 0; TIMER2->TIMER2_PRESCALER_REG = 0; From f0cc56485e5c07174d451ef8cd78f81027ffdfe4 Mon Sep 17 00:00:00 2001 From: Peter Csaszar Date: Fri, 25 Oct 2024 17:16:32 -0700 Subject: [PATCH 6/6] da1469x/clock: Protect register bitfields This commit adds masking to register bitfields, where a wrong syscfg value may result in the inadvertent overrides of neighboring bitfields. --- hw/mcu/dialog/da1469x/src/da1469x_clock.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 3e15980906..bf37a9ca27 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -111,7 +111,8 @@ da1469x_clock_sys_xtal32m_init(void) */ xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * XTALRDY_IRQ_FREQ_MAX / 1000000; - CRG_XTAL->XTALRDY_CTRL_REG = (xtalrdy_cnt << CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Pos) | + CRG_XTAL->XTALRDY_CTRL_REG = ((xtalrdy_cnt << CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Pos) & + CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk) | (DA1469X_XTALRDY_CLK_SEL << CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Pos); } @@ -294,7 +295,8 @@ da1469x_clock_calibrate(uint8_t clock_sel, uint16_t ref_cnt) /* Select reference clock & calibrated clock */ ANAMISC_BIF->CLK_REF_SEL_REG = (DA1469X_REF_SEL << ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Pos) | - (clock_sel << ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos); + ((clock_sel << ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos) & + ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Msk); /* Start measurement */ ANAMISC_BIF->CLK_REF_SEL_REG |= ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk; @@ -332,7 +334,7 @@ rc32k_trim_set(uint32_t trim) { CRG_TOP->CLK_RC32K_REG = (CRG_TOP->CLK_RC32K_REG & ~CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk) | - (trim << CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos); + ((trim << CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos) & CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk); } void