1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
 *******************************************************************************
 * @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 */