Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit 9083690

Browse files
hal: renesas: Update XTAL32M driver to support GF
1. Apply XTAL32M optimum values where necessary (if not available in CS in OTP). 2. Fine tune the XTAL32M ready signaling (by getting the time it took for the RDY signal to be asserted). Signed-off-by: Ioannis Karachalios <[email protected]>
1 parent 72e6780 commit 9083690

File tree

3 files changed

+124
-17
lines changed

3 files changed

+124
-17
lines changed

smartbond/da1469x_hal/da1469x_clock.c

Lines changed: 119 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,55 @@
2626
#include <da1469x_pd.h>
2727
#include <da1469x_pdc.h>
2828
#include <da1469x_otp.h>
29+
#include <da1469x_trimv.h>
2930

3031
#define XTAL32M_FREQ 32000000
3132
#define RC32M_FREQ 32000000
3233
#define PLL_FREQ 96000000
3334
#define XTAL32K_FREQ 32768
3435

36+
#define ARRAY_COUNT(_arr) (sizeof(_arr) / sizeof(_arr[0]))
37+
3538
static uint32_t g_mcu_clock_rcx_freq;
3639
static uint32_t g_mcu_clock_rc32k_freq;
3740
static uint32_t g_mcu_clock_rc32m_freq;
3841

3942
uint32_t SystemCoreClock = RC32M_FREQ;
4043

44+
#define CLK_FREQ_TRIM_REG_SET(_field, _val) \
45+
CRG_XTAL->CLK_FREQ_TRIM_REG = \
46+
((CRG_XTAL->CLK_FREQ_TRIM_REG & ~CRG_XTAL_CLK_FREQ_TRIM_REG_ ## _field ## _Msk) | \
47+
(((_val) << CRG_XTAL_CLK_FREQ_TRIM_REG_ ## _field ## _Pos) & \
48+
CRG_XTAL_CLK_FREQ_TRIM_REG_ ## _field ## _Msk))
49+
50+
#define CLK_FREQ_TRIM_REG_GET(_field) \
51+
((CRG_XTAL->CLK_FREQ_TRIM_REG & CRG_XTAL_CLK_FREQ_TRIM_REG_ ## _field ## _Msk) >> \
52+
CRG_XTAL_CLK_FREQ_TRIM_REG_ ## _field ## _Pos)
53+
54+
#define XTAL32M_CTRL2_REG_SET(_field, _val) \
55+
CRG_XTAL->XTAL32M_CTRL2_REG = \
56+
((CRG_XTAL->XTAL32M_CTRL2_REG & ~CRG_XTAL_XTAL32M_CTRL2_REG_ ## _field ## _Msk) | \
57+
(((_val) << CRG_XTAL_XTAL32M_CTRL2_REG_ ## _field ## _Pos) & \
58+
CRG_XTAL_XTAL32M_CTRL2_REG_ ## _field ## _Msk))
59+
60+
#define XTAL32M_CTRL2_REG_GET(_field) \
61+
((CRG_XTAL->XTAL32M_CTRL2_REG & CRG_XTAL_XTAL32M_CTRL2_REG_ ## _field ## _Msk) >> \
62+
CRG_XTAL_XTAL32M_CTRL2_REG_ ## _field ## _Pos)
63+
64+
#define XTALRDY_CTRL_REG_SET(_field, _val) \
65+
CRG_XTAL->XTALRDY_CTRL_REG = \
66+
((CRG_XTAL->XTALRDY_CTRL_REG & ~CRG_XTAL_XTALRDY_CTRL_REG_ ## _field ## _Msk) | \
67+
(((_val) << CRG_XTAL_XTALRDY_CTRL_REG_ ## _field ## _Pos) & \
68+
CRG_XTAL_XTALRDY_CTRL_REG_ ## _field ## _Msk))
69+
70+
#define XTALRDY_CTRL_REG_GET(_field) \
71+
((CRG_XTAL->XTALRDY_CTRL_REG & CRG_XTAL_XTALRDY_CTRL_REG_ ## _field ## _Msk) >> \
72+
CRG_XTAL_XTALRDY_CTRL_REG_ ## _field ## _Pos)
73+
74+
#define XTALRDY_STAT_REG_GET(_field) \
75+
((CRG_XTAL->XTALRDY_STAT_REG & CRG_XTAL_XTALRDY_STAT_REG_ ## _field ## _Msk) >> \
76+
CRG_XTAL_XTALRDY_STAT_REG_ ## _field ## _Pos)
77+
4178
/*
4279
OTPC is clocked by the system clock. Therefore, its timing settings
4380
should be adjusted upon system clock update.
@@ -98,23 +135,80 @@ da1469x_clock_sys_xtal32m_switch_check_restrictions(void)
98135
return ret;
99136
}
100137

138+
static void
139+
da1469x_clock_sys_xtal32m_configure(void)
140+
{
141+
assert(CRG_TOP->SYS_STAT_REG & CRG_TOP_SYS_STAT_REG_TIM_IS_UP_Msk);
142+
143+
/* Apply optimum values for XTAL32M registers not defined in CS section in OTP */
144+
static uint32_t regs_buf[] = {
145+
(uint32_t)&CRG_XTAL->CLK_FREQ_TRIM_REG
146+
};
147+
148+
bool status_buf[ARRAY_COUNT(regs_buf)];
149+
150+
da1469x_trimv_is_reg_pairs_in_otp(regs_buf, ARRAY_COUNT(regs_buf), status_buf);
151+
152+
if (!status_buf[0]) {
153+
CLK_FREQ_TRIM_REG_SET(XTAL32M_TRIM, CLK_FREQ_TRIM_REG__XTAL32M_TRIM__DEFAULT);
154+
}
155+
156+
/* Configure OSF BOOST */
157+
uint8_t cxcomp_phi_trim = 0;
158+
uint8_t cxcomp_trim_cap = XTAL32M_CTRL2_REG_GET(XTAL32M_CXCOMP_TRIM_CAP);
159+
160+
if (cxcomp_trim_cap < 37) {
161+
cxcomp_phi_trim = 3;
162+
} else {
163+
if (cxcomp_trim_cap < 123) {
164+
cxcomp_phi_trim = 2;
165+
}
166+
else {
167+
if (cxcomp_trim_cap < 170) {
168+
cxcomp_phi_trim = 1;
169+
}
170+
else {
171+
cxcomp_phi_trim = 0;
172+
}
173+
}
174+
}
175+
XTAL32M_CTRL2_REG_SET(XTAL32M_CXCOMP_PHI_TRIM, cxcomp_phi_trim);
176+
}
177+
178+
static void
179+
da1469x_clock_sys_xtal32m_rdy_cnt_update(int count, bool high_clock)
180+
{
181+
XTALRDY_CTRL_REG_SET(XTALRDY_CNT, count);
182+
XTALRDY_CTRL_REG_SET(XTALRDY_CLK_SEL, high_clock ? 1 : 0);
183+
}
184+
185+
static void
186+
da1469x_clock_sys_xtal32m_rdy_cnt_finetune(void)
187+
{
188+
#define XTALRDY_CTRL_REG_XTALRDY_CNT_MIN_LIMIT ( 4 )
189+
#define XTALRDY_CTRL_REG_XTALRDY_CNT_OFFSET ( 3 )
190+
191+
if (CRG_XTAL->XTAL32M_STAT1_REG & 0x100UL) {
192+
int16_t xtalrdy_cnt = XTALRDY_CTRL_REG_GET(XTALRDY_CNT);
193+
int16_t xtalrdy_stat = XTALRDY_CTRL_REG_XTALRDY_CNT_OFFSET - XTALRDY_STAT_REG_GET(XTALRDY_STAT);
194+
xtalrdy_cnt += xtalrdy_stat;
195+
196+
if (xtalrdy_cnt < XTALRDY_CTRL_REG_XTALRDY_CNT_MIN_LIMIT) {
197+
xtalrdy_cnt = XTALRDY_CTRL_REG_XTALRDY_CNT_MIN_LIMIT;
198+
}
199+
XTALRDY_CTRL_REG_SET(XTALRDY_CNT, xtalrdy_cnt);
200+
}
201+
}
202+
101203
void
102204
da1469x_clock_sys_xtal32m_init(void)
103205
{
104-
uint32_t reg;
105-
int xtalrdy_cnt;
106-
206+
da1469x_clock_sys_xtal32m_configure();
107207
/*
108208
* Number of 256kHz clock cycles (~4.085us) assuming worst case when actual frequency is 244800.
109209
* RC32M is in range <30.6, 32.6> so 256Khz can ba as low as 30.6MHz / 125 = 244.8kHz.
110210
*/
111-
xtalrdy_cnt = 1000 * 1000 / 4085;
112-
113-
reg = CRG_XTAL->XTALRDY_CTRL_REG;
114-
reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk);
115-
reg |= CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk;
116-
reg |= xtalrdy_cnt;
117-
CRG_XTAL->XTALRDY_CTRL_REG = reg;
211+
da1469x_clock_sys_xtal32m_rdy_cnt_update(1000 * 1000 / 4085, true);
118212
}
119213

120214
void
@@ -162,11 +256,22 @@ da1469x_clock_sys_xtal32m_wait_to_settle(void)
162256
uint32_t primask;
163257

164258
primask = DA1469X_IRQ_DISABLE();
165-
while (!da1469x_clock_is_xtal32m_settled()) {
166-
__WFE();
167-
__SEV();
168-
__WFE();
259+
260+
NVIC_ClearPendingIRQ(XTAL32M_RDY_IRQn);
261+
262+
if (!da1469x_clock_is_xtal32m_settled()) {
263+
NVIC_EnableIRQ(XTAL32M_RDY_IRQn);
264+
while (!NVIC_GetPendingIRQ(XTAL32M_RDY_IRQn)) {
265+
__WFE();
266+
__SEV();
267+
__WFE();
268+
}
269+
NVIC_DisableIRQ(XTAL32M_RDY_IRQn);
169270
}
271+
272+
/* XTALM32M_RDY_IRQn should be fired. The XTAL32M ready counter can be fine tuned. */
273+
da1469x_clock_sys_xtal32m_rdy_cnt_finetune();
274+
170275
DA1469X_IRQ_ENABLE(primask);
171276
}
172277

smartbond/da1469x_hal/da1469x_clock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
extern "C" {
2828
#endif
2929

30+
#ifndef CLK_FREQ_TRIM_REG__XTAL32M_TRIM__DEFAULT
31+
#define CLK_FREQ_TRIM_REG__XTAL32M_TRIM__DEFAULT 0x120
32+
#endif
33+
3034
/**
3135
* Initialize XTAL32M
3236
*/

smartbond/sdk/bsp/include/DA1469xAB.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,7 @@ typedef struct { /*!< (@ 0x50010000) CRG_XTAL Str
490490
__IOM uint32_t XTAL32M_CTRL1_REG; /*!< (@ 0x00000034) Control register for XTAL32M */
491491
__IOM uint32_t XTAL32M_CTRL2_REG; /*!< (@ 0x00000038) Control register for XTAL32M */
492492
__IOM uint32_t XTAL32M_CTRL3_REG; /*!< (@ 0x0000003C) Control register for XTAL32M */
493-
__IOM uint32_t XTAL32M_CTRL4_REG; /*!< (@ 0x00000040) Control register for XTAL32M */
494-
__IM uint32_t RESERVED3[3];
493+
__IM uint32_t RESERVED3[4];
495494
__IOM uint32_t XTAL32M_STAT0_REG; /*!< (@ 0x00000050) Status register for XTAL32M */
496495
__IOM uint32_t XTAL32M_STAT1_REG; /*!< (@ 0x00000054) Status register for XTAL32M */
497496
__IM uint32_t RESERVED4[2];
@@ -3250,7 +3249,6 @@ typedef struct { /*!< (@ 0x50000100) WAKEUP Struc
32503249
#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_BAND_SELECT_Msk (0x3c000UL) /*!< XTAL32M_RCOSC_BAND_SELECT (Bitfield-Mask: 0x0f) */
32513250
#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Pos (4UL) /*!< XTAL32M_RCOSC_TRIM (Bit 4) */
32523251
#define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Msk (0x3ff0UL) /*!< XTAL32M_RCOSC_TRIM (Bitfield-Mask: 0x3ff) */
3253-
/* =================================================== XTAL32M_CTRL4_REG =================================================== */
32543252
/* =================================================== XTAL32M_STAT0_REG =================================================== */
32553253
#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Pos (28UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bit 28) */
32563254
#define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Msk (0xf0000000UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bitfield-Mask: 0x0f) */

0 commit comments

Comments
 (0)