hpw422移植新的sdk
This commit is contained in:
@@ -0,0 +1,479 @@
|
||||
/*!
|
||||
* \file xc_drv_calib.c
|
||||
*
|
||||
* \brief Target xc calib driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_calib.h"
|
||||
#if XC_CHECK(XC_CALIB_ENABLED)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define RC_ADJ_VAL_MIN 0x0
|
||||
#define RC_ADJ_VAL_MID 0x1fff
|
||||
#define RC_ADJ_VAL_MAX 0x3fff
|
||||
|
||||
#define RANGE_LPO_RTM 0x400
|
||||
#define GEARS_HZ 1.56f
|
||||
#define _32K_STAND_HZ 32000
|
||||
#define _32K_STAND_300ppm_MAX 32010
|
||||
#define _32K_STAND_300ppm_MIN 31990
|
||||
#define CALIB_NUM 50 // ms
|
||||
|
||||
#define CALIB_TIME_MS 6 // ms
|
||||
|
||||
#define CALIB_STEP_CYCLE_32K (CALIB_TIME_MS * 32)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static volatile uint32_t mid = RC_ADJ_VAL_MID; // MID_LPO_RTM;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief xc_rc32k_calib_init
|
||||
* @details RC32k calibration initialization
|
||||
*
|
||||
* @param uint16_t - rc_adj_val
|
||||
* @retval void
|
||||
*/
|
||||
|
||||
void xc_rc32k_calib_init(uint16_t rc_adj_val)
|
||||
{
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)) {
|
||||
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(4U);
|
||||
|
||||
}
|
||||
else if (
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)
|
||||
#else
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(2U);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
}
|
||||
#if defined(CALIB_HFCLK_16M_CONFIG)
|
||||
else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M)
|
||||
{
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(8U);
|
||||
}
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_24M))
|
||||
{
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(8U);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
}
|
||||
#else
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_24M))
|
||||
{
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(8U);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
}
|
||||
#endif
|
||||
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(0x1UL);
|
||||
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(0x1UL);
|
||||
|
||||
rtc_rccal_lfcfg_set(0x100031);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
|
||||
rtc_rccal_hfcfg_set(25000);
|
||||
rtc_rccal_lim1_set(3);
|
||||
rtc_rccal_lim2_set(13);
|
||||
}
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_24M) ||
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)
|
||||
#else
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
rtc_rccal_hfcfg_set(37500);
|
||||
rtc_rccal_lim1_set(4);
|
||||
rtc_rccal_lim2_set(19);
|
||||
}
|
||||
|
||||
rtc_rccal_adj_step_set(0x1404);
|
||||
rtc_rccal_adj_val_set(0x1fff);
|
||||
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | rc_adj_val);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
rtc_rccal_inten_set(0x01);
|
||||
for (uint16_t dly = 0; dly < 1000; dly++)
|
||||
;
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_flfclk_calcu
|
||||
* @details Frequency lfclk value calculation
|
||||
*
|
||||
* @param uint32_t - hfcnt_val
|
||||
* @retval uint16_t - f_lfclk
|
||||
*/
|
||||
uint16_t xc_flfclk_calcu(uint32_t hfcnt_val)
|
||||
{
|
||||
uint32_t hfcnt_load = rtc_rccal_hfcfg_get();
|
||||
uint32_t lfdiv = rtc_rccal_lfcfg_get();
|
||||
|
||||
uint8_t hfcnt_dir = (hfcnt_val >> 31);
|
||||
uint16_t f_lfclk = 0;
|
||||
|
||||
if (hfcnt_dir == 0) {
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk =
|
||||
CLOCK_HFCLK_IN_16M * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
|
||||
}
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M))
|
||||
#else
|
||||
else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)
|
||||
#endif
|
||||
{
|
||||
f_lfclk = 24000000 * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
|
||||
}
|
||||
} else {
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = CLOCK_HFCLK_IN_16M * (lfdiv + 1) /
|
||||
(hfcnt_load + hfcnt_val - 0x80000000);
|
||||
}
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M))
|
||||
#else
|
||||
else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)
|
||||
#endif
|
||||
{
|
||||
f_lfclk =
|
||||
24000000 * (lfdiv + 1) / (hfcnt_load + hfcnt_val - 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
return f_lfclk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_rc32k_freq_scope
|
||||
* @details RC32k frequency scope
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
eLFREQ_Sta xc_rc32k_freq_scope(uint16_t freq)
|
||||
{
|
||||
eLFREQ_Sta ret = LFREQ_UNKNOW;
|
||||
uint16_t offset = (CLOCK_RC_LFCLK_IN_32K * 2 / 100);
|
||||
uint16_t rc32_offset_min = (CLOCK_RC_LFCLK_IN_32K - offset);
|
||||
uint16_t rc32_offset_max = CLOCK_RC_LFCLK_IN_32K;
|
||||
|
||||
if (freq < rc32_offset_min)
|
||||
ret = LFREQ_LOWER;
|
||||
else if (freq >= rc32_offset_max)
|
||||
ret = LFREQ_HIGHER;
|
||||
else
|
||||
ret = LFREQ_GOOD;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RC32k_Calib_by_hw
|
||||
* @details Calibrating RC32k through hardware.
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
void xc_rc32k_calib_by_hw(void)
|
||||
{
|
||||
uint16_t f_lfclk = 0;
|
||||
uint8_t rccal_int_sta;
|
||||
eLFREQ_Sta f_lf_sta;
|
||||
|
||||
xc_rc32k_calib_init(mid);
|
||||
|
||||
while (1) {
|
||||
|
||||
do {
|
||||
rccal_int_sta = rtc_rccal_intsta_get();
|
||||
} while (!(rccal_int_sta & 0x01));
|
||||
|
||||
rtc_rccal_inten_set(0x00);
|
||||
rtc_rccal_intsta_set(rccal_int_sta);
|
||||
|
||||
f_lfclk = xc_flfclk_calcu(rtc_rccal_hfcnt_val_get());
|
||||
|
||||
f_lf_sta = xc_rc32k_freq_scope(f_lfclk);
|
||||
if (LFREQ_GOOD != f_lf_sta) {
|
||||
rtc_rccal_en_set(0x00);
|
||||
// XC_RTC->RCCAL_EN = 0x00;
|
||||
if (f_lf_sta == LFREQ_LOWER) {
|
||||
mid += 100;
|
||||
if (mid > RC_ADJ_VAL_MAX) {
|
||||
mid = RC_ADJ_VAL_MIN;
|
||||
}
|
||||
} else {
|
||||
mid -= 10;
|
||||
if (mid < 10) {
|
||||
mid = RC_ADJ_VAL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
rtc_rccal_inten_set(0x01);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
} else {
|
||||
DEBUG("f_lfclk: %d\n", f_lfclk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x00001fff);
|
||||
rtc_rccal_adj_cfg__freq_adj_offset__setf(mid);
|
||||
rtc_rccal_adj_cfg__freq_adj_hw_clr__setf(0x01);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
|
||||
for (uint16_t dly = 0; dly < 1000; dly++)
|
||||
;
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief rc32k_calib_by_soft
|
||||
* @details Calibrate RC32k by software.
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
void xc_rc32k_calib_by_soft(void)
|
||||
{
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
uint8_t ao_intr;
|
||||
mid = RC_ADJ_VAL_MID;
|
||||
xc_rc32k_soft_calib_disable();
|
||||
xc_rc32k_calib_init(mid);
|
||||
|
||||
rtc_rccal_inten_set(0x00);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
while (1) {
|
||||
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(CALIB_STEP_CYCLE_32K);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
|
||||
do {
|
||||
|
||||
ao_intr = rtc_all_intr_ao_get();
|
||||
} while ((ao_intr & 0x20) == 0);
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = (uint32_t)((((float)((16.0) * CALIB_STEP_CYCLE_32K)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_24M) ||
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)
|
||||
#else
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
f_lfclk = (uint32_t)((((float)((24.0) * CALIB_STEP_CYCLE_32K)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
|
||||
if (f_lfclk > _32K_STAND_HZ) {
|
||||
mid = mid - ((uint32_t)(((float)(f_lfclk - _32K_STAND_HZ)) /
|
||||
(float)GEARS_HZ));
|
||||
} else if (f_lfclk < _32K_STAND_HZ) {
|
||||
mid = mid + ((uint32_t)(((float)(_32K_STAND_HZ - f_lfclk)) /
|
||||
(float)GEARS_HZ));
|
||||
}
|
||||
// DEBUG("f_lfclk: %u\n", f_lfclk);
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
|
||||
if (f_lfclk >= _32K_STAND_300ppm_MIN && f_lfclk <= _32K_STAND_300ppm_MAX)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_rc32k_soft_calib_start
|
||||
* @details Calibrate RC32k by software.only for 32M
|
||||
*
|
||||
* @param
|
||||
* @retval
|
||||
*/
|
||||
void xc_rc32k_soft_calib_start(void)
|
||||
{
|
||||
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
uint8_t ao_intr;
|
||||
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(32);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
|
||||
do {
|
||||
ao_intr = rtc_all_intr_ao_get();
|
||||
} while ((ao_intr & 0x20) == 0);
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
f_lfclk = (uint32_t)((((512000000)) / t32k_cnt)); //16.0*32
|
||||
|
||||
if (f_lfclk > 32000) {
|
||||
mid = mid - ((uint32_t)(((float)(f_lfclk - 32000)) /
|
||||
(float)GEARS_HZ));
|
||||
} else if (f_lfclk < 32000) {
|
||||
mid = mid + ((uint32_t)(((float)(32000 - f_lfclk)) /
|
||||
(float)GEARS_HZ));
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
|
||||
}
|
||||
|
||||
#define TIME_32K_CNT (32*2)
|
||||
#define ADJ_MAX (2)
|
||||
void xc_rc32k_soft_calib_enable(void)
|
||||
{
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(TIME_32K_CNT);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
}
|
||||
|
||||
void xc_rc32k_soft_calib_disable(void)
|
||||
{
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(0);
|
||||
NVIC_DisableIRQ(RTC_IRQn);
|
||||
}
|
||||
|
||||
void xc_rc32k_soft_calib_set(void)
|
||||
{
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = (uint32_t)((((float)((16.0) * TIME_32K_CNT)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
#if !defined(NO_SUPPORT_HFCLK_BBPLL_96M)
|
||||
else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M))
|
||||
#else
|
||||
else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)
|
||||
#endif
|
||||
{
|
||||
f_lfclk = (uint32_t)((((float)((24.0) * TIME_32K_CNT)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
|
||||
if (f_lfclk > 32000) {
|
||||
uint32_t diff = (uint32_t)(((float)(f_lfclk - 32000)) /
|
||||
(float)GEARS_HZ);
|
||||
if(diff > ADJ_MAX){
|
||||
diff = ADJ_MAX;
|
||||
}
|
||||
mid = mid - diff;
|
||||
} else if (f_lfclk < 32000) {
|
||||
uint32_t diff = (uint32_t)(((float)(32000 - f_lfclk)) /
|
||||
(float)GEARS_HZ);
|
||||
if(diff > ADJ_MAX){
|
||||
diff = ADJ_MAX;
|
||||
}
|
||||
mid = mid + diff;
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
#endif // XC_CHECK(XC_CALIB_ENABLED)
|
||||
Reference in New Issue
Block a user