@@ -358,10 +358,83 @@ da1469x_clock_lp_rcx_calibrate(void)
358358 g_mcu_clock_rcx_freq = da1469x_clock_calibrate (3 , MCU_RCX_CAL_REF_CNT );
359359}
360360
361+ #define RC32K_TARGET_FREQ 32000
362+ #define RC32K_TRIM_MIN 0
363+ #define RC32K_TRIM_MAX 15
364+
365+ static inline uint32_t
366+ rc32k_trim_get (void )
367+ {
368+ return (CRG_TOP -> CLK_RC32K_REG & CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk ) >>
369+ CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos ;
370+ }
371+
372+ static inline void
373+ rc32k_trim_set (uint32_t trim )
374+ {
375+ CRG_TOP -> CLK_RC32K_REG =
376+ (CRG_TOP -> CLK_RC32K_REG & ~CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk ) |
377+ (trim << CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos );
378+ }
379+
361380void
362381da1469x_clock_lp_rc32k_calibrate (void )
363382{
364- g_mcu_clock_rc32k_freq = da1469x_clock_calibrate (0 , 100 );
383+ uint32_t trim ;
384+ uint32_t trim_prev ;
385+ uint32_t freq ;
386+ uint32_t freq_prev ;
387+ uint32_t freq_delta ;
388+ uint32_t freq_delta_prev ;
389+ bool trim_ok ;
390+
391+ if (!(CRG_TOP -> CLK_RC32K_REG & CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk )) {
392+ return ;
393+ }
394+
395+ freq = 0 ;
396+ freq_delta = INT32_MAX ;
397+
398+ trim = rc32k_trim_get ();
399+ trim_prev = trim ;
400+ trim_ok = false;
401+
402+ do {
403+ freq_prev = freq ;
404+ freq_delta_prev = freq_delta ;
405+
406+ freq = da1469x_clock_calibrate (0 , 1 );
407+
408+ freq_delta = freq - RC32K_TARGET_FREQ ;
409+ freq_delta = (int32_t )freq_delta < 0 ? - freq_delta : freq_delta ;
410+
411+ if (freq_delta > freq_delta_prev ) {
412+ /* Previous trim value was closer to target frequency, use it */
413+ freq = freq_prev ;
414+ rc32k_trim_set (trim_prev );
415+ trim_ok = true;
416+ } else if (freq > RC32K_TARGET_FREQ ) {
417+ /* Decrease trim value if possible */
418+ if (trim > RC32K_TRIM_MIN ) {
419+ trim_prev = trim ;
420+ rc32k_trim_set (-- trim );
421+ } else {
422+ trim_ok = true;
423+ }
424+ } else if (freq < RC32K_TARGET_FREQ ) {
425+ /* Increase trim value if possible */
426+ if (trim < RC32K_TRIM_MAX ) {
427+ trim_prev = trim ;
428+ rc32k_trim_set (++ trim );
429+ } else {
430+ trim_ok = true;
431+ }
432+ } else {
433+ trim_ok = true;
434+ }
435+ } while (!trim_ok );
436+
437+ g_mcu_clock_rc32k_freq = freq ;
365438}
366439
367440void
0 commit comments