214 lines
6.3 KiB
C
214 lines
6.3 KiB
C
/*!
|
|
* \file xc_drv_rtc.c
|
|
*
|
|
* \brief Target xc aotimer 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 "xc6xxx.h"
|
|
/*------------------------------------------------------------------------------------
|
|
Local Variables
|
|
-------------------------------------------------------------------------------------*/
|
|
static volatile uint8_t calibration_flag = 0;
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
Global Variables
|
|
-------------------------------------------------------------------------------------*/
|
|
|
|
uint8_t AO_Timer_Callback(uint8_t calib_flag);
|
|
|
|
RTC_Intr_Cb_t RTC_Intr_cb = {
|
|
AO_Timer_Callback,
|
|
T1_CMR_Callback,
|
|
T2_CMR_Callback,
|
|
T3_CMR_Callback,
|
|
Sec_Callback,
|
|
Min_Callback,
|
|
Hour_Callback,
|
|
Day_Callback};
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
Func Prototype
|
|
-------------------------------------------------------------------------------------*/
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
Functions
|
|
-------------------------------------------------------------------------------------*/
|
|
void xc_rtc_start(void) { rtc_icr__rtc__cnt_e__setf(RTC_ICR_CNTE_ENABLE); }
|
|
|
|
void xc_rtc_stop(void) { rtc_icr__rtc__cnt_e__setf(RTC_ICR_CNTE_DISABLE); }
|
|
|
|
static void xc_rtc_matchtime_set(RTC_InitCfg_t *rtc_cfg)
|
|
{
|
|
if (rtc_cfg->MatchTime.ch == RTC_MATCH_T1) {
|
|
rtc_cmr_one_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
|
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
|
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T2) {
|
|
rtc_cmr_two_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
|
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
|
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T3) {
|
|
rtc_cmr_three_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
|
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
|
}
|
|
}
|
|
|
|
void xc_rtc_date_get(Rtc_DateTypeDef_t *Date) { __rtc_dateget(Date); }
|
|
|
|
void xc_rtc_init(RTC_InitCfg_t *rtc_cfg)
|
|
{
|
|
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(ENABLE);
|
|
|
|
cprao_aon_clken_grctl__rtc_clk_en__setf(ENABLE);
|
|
|
|
rtc_icr_set(DISABLE);
|
|
|
|
rtc_raw_limit__setf(xc_clock_lfclk_in_get());
|
|
|
|
rtc_datelimitSet(rtc_cfg);
|
|
rtc_dateSet(rtc_cfg);
|
|
|
|
if (rtc_cfg->MatchTimeEnable) {
|
|
xc_rtc_matchtime_set(rtc_cfg);
|
|
rtc_config_matchtimeit(rtc_cfg);
|
|
}
|
|
|
|
if (rtc_cfg->SecIT_Enable) {
|
|
rtc_config_secit(rtc_cfg);
|
|
}
|
|
if (rtc_cfg->MinIT_Enable) {
|
|
rtc_config_minit(rtc_cfg);
|
|
}
|
|
if (rtc_cfg->HourIT_Enable) {
|
|
rtc_config_hourit(rtc_cfg);
|
|
}
|
|
if (rtc_cfg->DayIT_Enable) {
|
|
rtc_config_dayit(rtc_cfg);
|
|
}
|
|
}
|
|
|
|
uint8_t AO_Timer_Callback(uint8_t calib_flag)
|
|
{
|
|
calib_flag = 1;
|
|
return calib_flag;
|
|
}
|
|
|
|
void RTC_Handler(void)
|
|
{
|
|
uint32_t val;
|
|
|
|
val = rtc_all_intr_ao_get();
|
|
|
|
if (val & RTC_AO_ALL_INTR_AO_TIMER_INTR_Msk) {
|
|
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(RTC_AO_TIMER_CTL_AO_TIMER_CLR_SET);
|
|
rtc_ao_timer_ctl__rtc_ao_timer_en__setf(RTC_AO_TIMER_CTL_AO_TIMER_EN_DISABLE);
|
|
|
|
calibration_flag = RTC_Intr_cb.AO_Timer_Callback(calibration_flag);
|
|
}
|
|
|
|
val = rtc_isr_eoi_get();
|
|
|
|
if (val) {
|
|
rtc_isr_eoi_set(val);
|
|
|
|
if ((val & RTC_ICR_T1E_Msk) == RTC_ICR_T1E_Msk){
|
|
RTC_Intr_cb.T1_CMR_Callback();
|
|
}
|
|
if ((val & RTC_ICR_T2E_Msk) == RTC_ICR_T2E_Msk){
|
|
RTC_Intr_cb.T2_CMR_Callback();
|
|
}
|
|
if ((val & RTC_ICR_T3E_Msk) == RTC_ICR_T3E_Msk){
|
|
RTC_Intr_cb.T3_CMR_Callback();
|
|
}
|
|
|
|
if ((val & RTC_ICR_DaE_Msk) == RTC_ICR_DaE_Msk){
|
|
RTC_Intr_cb.Day_Callback();
|
|
}
|
|
if ((val & RTC_ICR_HoE_Msk) == RTC_ICR_HoE_Msk){
|
|
RTC_Intr_cb.Hour_Callback();
|
|
}
|
|
if ((val & RTC_ICR_MiE_Msk) == RTC_ICR_MiE_Msk){
|
|
RTC_Intr_cb.Min_Callback();
|
|
}
|
|
if ((val & RTC_ICR_SeE_Msk) == RTC_ICR_SeE_Msk){
|
|
RTC_Intr_cb.Sec_Callback();
|
|
}
|
|
}
|
|
}
|
|
|
|
__WEAK uint8_t T1_CMR_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t T2_CMR_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t T3_CMR_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t Sec_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t Min_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t Hour_Callback(void) { return 0; }
|
|
|
|
__WEAK uint8_t Day_Callback(void) { return 0; }
|
|
|
|
/***********************************************************************************
|
|
***************************** RC32 Calibration
|
|
******************************
|
|
***********************************************************************************/
|
|
/**
|
|
* @brief RC32k_Count_Calib
|
|
* @details 鏍″噯 RC32K 瀹為檯璁℃暟鍊?
|
|
*
|
|
* @param RTC 瀵勫瓨鍣ㄧ储寮?
|
|
* @retval uint8_t
|
|
*/
|
|
uint8_t xc_rc32k_count_calib()
|
|
{
|
|
volatile int32_t hw_timeout = 10000;
|
|
uint32_t val;
|
|
float freq = 0.0;
|
|
|
|
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(32);
|
|
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
|
|
|
while ((!(calibration_flag)) && (hw_timeout > 0)) {
|
|
__nop();
|
|
hw_timeout--;
|
|
}
|
|
|
|
if (hw_timeout < 0) {
|
|
return 1;
|
|
}
|
|
|
|
val = rtc_freq_32k_timer_val_get();
|
|
val *= (32000000.0f / xc_clock_hfclk_in_get());
|
|
|
|
rtc_ao_timer_ctl__rtc_ao_timer_en__setf(DISABLE);
|
|
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(ENABLE);
|
|
|
|
freq = (float)(15625.0f / (float)val) * 32768.0f;
|
|
DEBUG("Calib freq: %u\n", (uint32_t)freq);
|
|
|
|
rtc_raw_limit__setf((uint32_t)freq);
|
|
|
|
return 0;
|
|
}
|