/**
|
*******************************************************************************
|
* @file soc_32k_cali.c
|
* @create 2024-12-11
|
* @author Panchip BLE GROUP
|
* @note
|
* Copyright (c) 2022-2024 Shanghai Panchip Microelectronics Co.,Ltd.
|
*
|
*******************************************************************************
|
*/
|
#include "soc_api.h"
|
|
/* For RCL Clock test */
|
//#define PRINT_RCL_FREQ_BEFORE_AND_AFTER_CALIBRATE
|
|
#define DST_CLK_CNT 100 /* measure 100 clock-32k period */
|
|
#if (CONFIG_LOW_SPEED_CLOCK_SRC == 1)
|
uint32_t clk_32k_freq = 32768;
|
#else
|
uint32_t clk_32k_freq = 32000;
|
#endif
|
|
|
uint32_t clktrim_measure_32k_clk(uint32_t dst_clk_cnt)
|
{
|
uint32_t counter_result;
|
uint32_t calib_freq;
|
|
CLK_EnableClkTrim(ENABLE);
|
CLK_SelectClkTrimSrc(CLKTRIM_CALC_CLK_SEL_32K);
|
|
TRIM_SetCalCnt(TRIM, dst_clk_cnt);
|
|
TRIM_StartTuning(TRIM, TRIM_MEASURE_TUNING_EN_Msk);
|
while (!TRIM_IsIntStatusOccured(TRIM, TRIM_FLAG_MEASURE_STOP_Msk)) {
|
/* busy-wait */
|
}
|
TRIM_ClearIntStatusMsk(TRIM, TRIM_FLAG_MEASURE_STOP_Msk);
|
counter_result = TRIM_GetRealCnt(TRIM);
|
|
calib_freq = ((uint64_t)FREQ_32MHZ * (uint64_t)dst_clk_cnt) / counter_result;
|
clk_32k_freq = calib_freq;
|
CLK_EnableClkTrim(DISABLE);
|
|
return calib_freq;
|
}
|
|
CONFIG_RAM_CODE void clktrim_32k_clk_measure_start(uint32_t dst_clk_cnt)
|
{
|
CLK_EnableClkTrim(ENABLE);
|
CLK_SelectClkTrimSrc(CLKTRIM_CALC_CLK_SEL_32K);
|
TRIM_SetCalCnt(TRIM, dst_clk_cnt);
|
|
TRIM_StartTuning(TRIM, TRIM_MEASURE_TUNING_EN_Msk);
|
}
|
|
CONFIG_RAM_CODE uint32_t clktrim_32k_clk_measure_value_get(void)
|
{
|
uint32_t counter_result;
|
|
while (!TRIM_IsIntStatusOccured(TRIM, TRIM_FLAG_MEASURE_STOP_Msk)) {
|
/* busy-wait */
|
}
|
TRIM_ClearIntStatusMsk(TRIM, TRIM_FLAG_MEASURE_STOP_Msk);
|
counter_result = TRIM_GetRealCnt(TRIM);
|
|
CLK_EnableClkTrim(DISABLE);
|
|
return counter_result;
|
}
|
|
#if (CONFIG_LOW_SPEED_CLOCK_SRC == 0)
|
void calibrate_rcl_clk(uint32_t expected_freq)
|
{
|
uint32_t AHB_clk_reg;
|
|
const uint8_t coarse_tune_bitwidth = 3;
|
const uint8_t fine_tune_bitwidth = 7;
|
|
#ifdef PRINT_RCL_FREQ_BEFORE_AND_AFTER_CALIBRATE
|
printf("RCL Freq before calib: %d Hz\n", clktrim_measure_32k_clk(DST_CLK_CNT));
|
#endif
|
|
AHB_clk_reg = CLK->AHB_CLK_CTRL;
|
CLK->AHB_CLK_CTRL |= CLK_AHBPeriph_APB2;
|
|
TRIM_EnableInt(TRIM, ENABLE);
|
|
/* Start calibration */
|
/* Disable hardware calculate. */
|
ANA->RCL_HW_CAL_CTRL &= ~ANAC_RCL_HW_CAL_EN_Msk;
|
/* Enable Clktrim */
|
CLK_SelectClkTrimSrc(CLKTRIM_CALC_CLK_SEL_32K);
|
CLK_EnableClkTrim(ENABLE);
|
|
TRIM_SetCalCnt(TRIM, DST_CLK_CNT);
|
TRIM_SetIdealCnt(TRIM, FREQ_32MHZ / expected_freq * DST_CLK_CNT - 1);
|
|
/* a. Coarse tuning proc */
|
TRIM_SetBitWidth(TRIM, coarse_tune_bitwidth);
|
TRIM_SetCoarseCode(TRIM, 1 << coarse_tune_bitwidth);
|
TRIM_StartTuning(TRIM, TRIM_COARSE_TUNING_EN_Msk);
|
while (!TRIM_IsIntStatusOccured(TRIM, TRIM_FLAG_CTUNE_STOP_Msk)) {
|
/* busy-wait */
|
}
|
TRIM_ClearIntStatusMsk(TRIM, TRIM_FLAG_CTUNE_STOP_Msk);
|
|
/* b. Fine tuning proc */
|
TRIM_SetBitWidth(TRIM, fine_tune_bitwidth);
|
TRIM_SetFineCode(TRIM, 1 << fine_tune_bitwidth);
|
TRIM_StartTuning(TRIM, TRIM_FINE_TUNING_EN_Msk);
|
while (!TRIM_IsIntStatusOccured(TRIM, TRIM_FLAG_FTUNE_STOP_Msk)) {
|
/* busy-wait */
|
}
|
TRIM_ClearIntStatusMsk(TRIM, TRIM_FLAG_FTUNE_STOP_Msk);
|
|
/* Disable Clktrim */
|
CLK_EnableClkTrim(DISABLE);
|
|
CLK->AHB_CLK_CTRL = AHB_clk_reg;
|
|
#ifdef PRINT_RCL_FREQ_BEFORE_AND_AFTER_CALIBRATE
|
printf("RCL Freq after calib: %d Hz\n", clktrim_measure_32k_clk(DST_CLK_CNT));
|
#endif
|
}
|
#endif /* CONFIG_LOW_SPEED_CLOCK_SRC == 0 */
|