BLE5.2 1.0
开发文档说明
xc_drv_calib.c
浏览该文件的文档.
1
25/*-----------------------------------------------------------------------------------
26 INCLUDE HEADE FILES
27 ------------------------------------------------------------------------------------*/
28#include "xc_drv_calib.h"
29
30/*------------------------------------------------------------------------------------
31 Macros
32 -------------------------------------------------------------------------------------*/
33#define RC_ADJ_VAL_MIN 0x0
34#define RC_ADJ_VAL_MID 0x1fff
35#define RC_ADJ_VAL_MAX 0x3fff
36
37#define RANGE_LPO_RTM 0x400
38#define GEARS_HZ 1.56f
39#define _32K_STAND_HZ 32000
40
41#define CALIB_NUM 50 // ms
42
43#define CALIB_TIME_MS 10 // ms
44#define CALIB_DELAY_CHECK (CALIB_TIME_MS + 20) // ms
45
46#define CALIB_STEP_CYCLE_32K (CALIB_TIME_MS * 32)
47
48/*------------------------------------------------------------------------------------
49 Local Variables
50 -------------------------------------------------------------------------------------*/
51static volatile uint32_t mid = RC_ADJ_VAL_MID; // MID_LPO_RTM;
52
53/*------------------------------------------------------------------------------------
54 Global Variables
55 -------------------------------------------------------------------------------------*/
56
57/*------------------------------------------------------------------------------------
58 Func Prototype
59 -------------------------------------------------------------------------------------*/
60
61/*------------------------------------------------------------------------------------
62 Functions
63 -------------------------------------------------------------------------------------*/
72void xc_rc32k_calib_init(uint16_t rc_adj_val)
73{
76
77 cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
78 cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(4U);
79
80 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) ||
82
83 cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(2U);
84 cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
85
86 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M)) {
87
88 cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
89 cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(8U);
90 }
91
92 cpr_ctlapbclken_grctl__rtc_pclk_en__setf(0x1UL);
93
94 cprao_aon_clken_grctl__rtc_clk_en__setf(0x1UL);
95
96 rtc_rccal_lfcfg_set(0x100031);
97
101
102 rtc_rccal_hfcfg_set(25000);
103 rtc_rccal_lim1_set(3);
104 rtc_rccal_lim2_set(13);
105 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
107
108 rtc_rccal_hfcfg_set(37500);
109 rtc_rccal_lim1_set(4);
110 rtc_rccal_lim2_set(19);
111 }
112
113 rtc_rccal_adj_step_set(0x1404);
114 rtc_rccal_adj_val_set(0x1fff);
115
116 rtc_rccal_adj_cfg_set(0x1fff4000 | rc_adj_val);
117 rtc_rccal_intsta_set(0x03);
118 rtc_rccal_inten_set(0x01);
119 for (uint16_t dly = 0; dly < 1000; dly++)
120 ;
121 rtc_rccal_en_set(0x01);
122}
123
131uint16_t xc_flfclk_calcu(uint32_t hfcnt_val)
132{
133 uint32_t hfcnt_load = rtc_rccal_hfcfg_get();
134 uint32_t lfdiv = rtc_rccal_lfcfg_get();
135
136 uint8_t hfcnt_dir = (hfcnt_val >> 31);
137 uint16_t f_lfclk = 0;
138
139 if (hfcnt_dir == 0) {
143 f_lfclk =
144 CLOCK_HFCLK_IN_16M * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
145 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
147 f_lfclk = 24000000 * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
148 }
149 } else {
153 f_lfclk = CLOCK_HFCLK_IN_16M * (lfdiv + 1) /
154 (hfcnt_load + hfcnt_val - 0x80000000);
155 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
157 f_lfclk =
158 24000000 * (lfdiv + 1) / (hfcnt_load + hfcnt_val - 0x80000000);
159 }
160 }
161
162 return f_lfclk;
163}
164
173{
175 uint16_t offset = (CLOCK_RC_LFCLK_IN_32K * 2 / 100);
176 uint16_t rc32_offset_min = (CLOCK_RC_LFCLK_IN_32K - offset);
177 uint16_t rc32_offset_max = CLOCK_RC_LFCLK_IN_32K;
178
179 if (freq < rc32_offset_min)
180 ret = LFREQ_LOWER;
181 else if (freq >= rc32_offset_max)
182 ret = LFREQ_HIGHER;
183 else
184 ret = LFREQ_GOOD;
185
186 return ret;
187}
188
197{
198 uint16_t f_lfclk = 0;
199 uint8_t rccal_int_sta;
200 eLFREQ_Sta f_lf_sta;
201
203
204 while (1) {
205
206 do {
207 rccal_int_sta = rtc_rccal_intsta_get();
208 } while (!(rccal_int_sta & 0x01));
209
210 rtc_rccal_inten_set(0x00);
211 rtc_rccal_intsta_set(rccal_int_sta);
212
213 f_lfclk = xc_flfclk_calcu(rtc_rccal_hfcnt_val_get());
214
215 f_lf_sta = xc_rc32k_freq_scope(f_lfclk);
216 if (LFREQ_GOOD != f_lf_sta) {
217 rtc_rccal_en_set(0x00);
218// XC_RTC->RCCAL_EN = 0x00;
219 if (f_lf_sta == LFREQ_LOWER) {
220 mid += 100;
221 if (mid > RC_ADJ_VAL_MAX) {
222 mid = RC_ADJ_VAL_MIN;
223 }
224 } else {
225 mid -= 10;
226 if (mid < 10) {
227 mid = RC_ADJ_VAL_MAX;
228 }
229 }
230
231 rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
232 rtc_rccal_inten_set(0x01);
233
234 rtc_rccal_en_set(0x01);
235 } else {
236 DEBUG("f_lfclk: %d\n", f_lfclk);
237 break;
238 }
239 }
240
241 rtc_rccal_en_set(0x00);
242 rtc_rccal_adj_cfg_set(0x00001fff);
243 rtc_rccal_adj_cfg__freq_adj_offset__setf(mid);
244 rtc_rccal_adj_cfg__freq_adj_hw_clr__setf(0x01);
245 rtc_rccal_intsta_set(0x03);
246
247 for (uint16_t dly = 0; dly < 1000; dly++)
248 ;
249
250 rtc_rccal_en_set(0x01);
251}
252
253
254
263{
264 uint32_t f_lfclk = 0;
265 uint32_t t32k_cnt = 0;
266 uint8_t ao_intr;
267
269
270 rtc_rccal_inten_set(0x00);
271 rtc_rccal_intsta_set(0x03);
272 while (1) {
273
274 rtc_ao_timer_ctl_set(0);
275 rtc_ao_timer_ctl__rtc_ao_timer_value__setf(CALIB_STEP_CYCLE_32K);
276 rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
277
278 do {
279
280 ao_intr = rtc_all_intr_ao_get();
281 } while ((ao_intr & 0x20) == 0);
282
283 t32k_cnt = rtc_freq_32k_timer_val_get();
284
285 rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
286 rtc_ao_timer_ctl_set(0);
287
291 f_lfclk = (uint32_t)((((float)((16.0) * CALIB_STEP_CYCLE_32K)) /
292 t32k_cnt) *
293 1000000);
294 } else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
296 f_lfclk = (uint32_t)((((float)((24.0) * CALIB_STEP_CYCLE_32K)) /
297 t32k_cnt) *
298 1000000);
299 }
300
301 if (f_lfclk > _32K_STAND_HZ) {
302 mid = mid - ((uint32_t)(((float)(f_lfclk - _32K_STAND_HZ)) /
303 (float)GEARS_HZ));
304 } else if (f_lfclk < _32K_STAND_HZ) {
305 mid = mid + ((uint32_t)(((float)(_32K_STAND_HZ - f_lfclk)) /
306 (float)GEARS_HZ));
307 }
308 DEBUG("f_lfclk: %d\n", f_lfclk);
309
310 rtc_rccal_en_set(0x00);
311 rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
312
313 rtc_rccal_en_set(0x01);
314
315 if (f_lfclk == _32K_STAND_HZ)
316 break;
317 }
318}
void xc_rc32k_calib_by_hw(void)
RC32k_Calib_by_hw
static volatile uint32_t mid
eLFREQ_Sta xc_rc32k_freq_scope(uint16_t freq)
xc_rc32k_freq_scope
void xc_rc32k_calib_init(uint16_t rc_adj_val)
xc_rc32k_calib_init
uint16_t xc_flfclk_calcu(uint32_t hfcnt_val)
xc_flfclk_calcu
void xc_rc32k_calib_by_soft(void)
rc32k_calib_by_soft
The header of xc_drv_calib.c
@ CLOCK_RC_LFCLK_IN_32K
eLFREQ_Sta
@ LFREQ_UNKNOW
@ LFREQ_HIGHER
@ LFREQ_GOOD
@ LFREQ_LOWER
CLOCK_HFCLK_In_Typedef xc_clock_hfclk_in_get(void)
xc_clock_hfclk_in_get
@ CLOCK_HFCLK_IN_16M
@ CLOCK_HFCLK_IN_96M
@ CLOCK_HFCLK_IN_48M
@ CLOCK_HFCLK_IN_32M
@ CLOCK_HFCLK_IN_64M