625 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			625 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /********************************** (C) COPYRIGHT *******************************
 | |||
|  |  * File Name          : CH59x_clk.c | |||
|  |  * Author             : WCH | |||
|  |  * Version            : V1.2 | |||
|  |  * Date               : 2021/11/17 | |||
|  |  * Description | |||
|  |  ********************************************************************************* | |||
|  |  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | |||
|  |  * Attention: This software (modified or not) and binary are used for  | |||
|  |  * microcontroller manufactured by Nanjing Qinheng Microelectronics. | |||
|  |  *******************************************************************************/ | |||
|  | 
 | |||
|  | #include "CH59x_common.h"
 | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      LClk32K_Select | |||
|  |  * | |||
|  |  * @brief   32K 低频时钟来源 | |||
|  |  * | |||
|  |  * @param   hc  - 选择32K使用内部还是外部 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void LClk32K_Select(LClk32KTypeDef hc) | |||
|  | { | |||
|  |     uint8_t cfg = R8_CK32K_CONFIG; | |||
|  | 
 | |||
|  |     if(hc == Clk32K_LSI) | |||
|  |     { | |||
|  |         cfg &= ~RB_CLK_OSC32K_XT; | |||
|  |         LSECFG_Current(LSE_RCur_100); | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         cfg |= RB_CLK_OSC32K_XT; | |||
|  |     } | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_CK32K_CONFIG = cfg; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      LClk32K_Cfg | |||
|  |  * | |||
|  |  * @brief   32K 低频时钟电源配置 | |||
|  |  * | |||
|  |  * @param   hc  - 选择内部32K还是外部32K | |||
|  |  * @param   s   - 是否打开电源 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void LClk32K_Cfg(LClk32KTypeDef hc, FunctionalState s) | |||
|  | { | |||
|  |     uint8_t cfg = R8_CK32K_CONFIG; | |||
|  | 
 | |||
|  |     if(hc == Clk32K_LSI) | |||
|  |     { | |||
|  |         if(s == DISABLE) | |||
|  |         { | |||
|  |             cfg &= ~RB_CLK_INT32K_PON; | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             cfg |= RB_CLK_INT32K_PON; | |||
|  |         } | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         if(s == DISABLE) | |||
|  |         { | |||
|  |             cfg &= ~RB_CLK_XT32K_PON; | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             cfg |= RB_CLK_XT32K_PON; | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_CK32K_CONFIG = cfg; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      HSECFG_Current | |||
|  |  * | |||
|  |  * @brief   HSE晶体 偏置电流配置 | |||
|  |  * | |||
|  |  * @param   c   - 75%,100%,125%,150% | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void HSECFG_Current(HSECurrentTypeDef c) | |||
|  | { | |||
|  |     uint8_t x32M_c; | |||
|  | 
 | |||
|  |     x32M_c = R8_XT32M_TUNE; | |||
|  |     x32M_c = (x32M_c & 0xfc) | (c & 0x03); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_XT32M_TUNE = x32M_c; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      HSECFG_Capacitance | |||
|  |  * | |||
|  |  * @brief   HSE晶体 负载电容配置 | |||
|  |  * | |||
|  |  * @param   c   - refer to HSECapTypeDef | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void HSECFG_Capacitance(HSECapTypeDef c) | |||
|  | { | |||
|  |     uint8_t x32M_c; | |||
|  | 
 | |||
|  |     x32M_c = R8_XT32M_TUNE; | |||
|  |     x32M_c = (x32M_c & 0x8f) | (c << 4); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_XT32M_TUNE = x32M_c; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      LSECFG_Current | |||
|  |  * | |||
|  |  * @brief   LSE晶体 偏置电流配置 | |||
|  |  * | |||
|  |  * @param   c   - 70%,100%,140%,200% | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void LSECFG_Current(LSECurrentTypeDef c) | |||
|  | { | |||
|  |     uint8_t x32K_c; | |||
|  | 
 | |||
|  |     x32K_c = R8_XT32K_TUNE; | |||
|  |     x32K_c = (x32K_c & 0xfc) | (c & 0x03); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_XT32K_TUNE = x32K_c; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      LSECFG_Capacitance | |||
|  |  * | |||
|  |  * @brief   LSE晶体 负载电容配置 | |||
|  |  * | |||
|  |  * @param   c   - refer to LSECapTypeDef | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void LSECFG_Capacitance(LSECapTypeDef c) | |||
|  | { | |||
|  |     uint8_t x32K_c; | |||
|  | 
 | |||
|  |     x32K_c = R8_XT32K_TUNE; | |||
|  |     x32K_c = (x32K_c & 0x0f) | (c << 4); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_XT32K_TUNE = x32K_c; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      Calibration_LSI | |||
|  |  * | |||
|  |  * @brief   校准内部32K时钟 | |||
|  |  * | |||
|  |  * @param   cali_Lv - 校准等级选择    Level_32 :2.4ms   1000ppm (32M 主频)  1100ppm (60M 主频) | |||
|  |  *                                   Level_64 :4.4ms   800ppm  (32M 主频)  1000ppm (60M 主频) | |||
|  |  *                                   Level_128 :8.4ms  600ppm  (32M 主频)  800ppm  (60M 主频)                                                          | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void Calibration_LSI(Cali_LevelTypeDef cali_Lv) | |||
|  | { | |||
|  |     UINT64 i; | |||
|  |     long long cnt_offset; | |||
|  |     UINT8  retry = 0; | |||
|  |     UINT8  retry_all = 0; | |||
|  |     INT32  freq_sys; | |||
|  |     UINT32 cnt_32k = 0; | |||
|  |     UINT32 irqv = 0; | |||
|  | 
 | |||
|  |     freq_sys = GetSysClock(); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_CK32K_CONFIG &= ~RB_CLK_OSC32K_FILT; | |||
|  |     R8_CK32K_CONFIG |= RB_CLK_OSC32K_FILT; | |||
|  |     sys_safe_access_disable(); | |||
|  |     LSECFG_Current(LSE_RCur_100); | |||
|  | 
 | |||
|  |     while(1) | |||
|  |     { | |||
|  |         // 粗调
 | |||
|  |         sys_safe_access_enable(); | |||
|  |         R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_TOTAL; | |||
|  |         R8_OSC_CAL_CTRL |= 1; | |||
|  |         sys_safe_access_disable(); | |||
|  | 
 | |||
|  |         while(1) | |||
|  |         { | |||
|  |             sys_safe_access_enable(); | |||
|  |             R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |             R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |             R16_OSC_CAL_CNT |= RB_OSC_CAL_IF; | |||
|  |             sys_safe_access_disable(); | |||
|  |             while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 ) | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |                 sys_safe_access_disable(); | |||
|  |             } | |||
|  | 
 | |||
|  |             while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); // 用于丢弃
 | |||
|  | 
 | |||
|  |             SYS_DisableAllIrq(&irqv); | |||
|  |             sys_safe_access_enable(); | |||
|  |             R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN; | |||
|  |             R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |             R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |             R16_OSC_CAL_CNT |= RB_OSC_CAL_IF; | |||
|  |             sys_safe_access_disable(); | |||
|  |             while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 ) | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |                 sys_safe_access_disable(); | |||
|  |             } | |||
|  | 
 | |||
|  |             while(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT); | |||
|  |             cnt_32k = RTC_GetCycle32k(); | |||
|  |             while(RTC_GetCycle32k() == cnt_32k); | |||
|  |             R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |             SYS_RecoverIrq(irqv); | |||
|  |             while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); | |||
|  |             i = R16_OSC_CAL_CNT; // 实时校准后采样值
 | |||
|  |             cnt_offset = (i & 0x3FFF) + R8_OSC_CAL_OV_CNT * 0x3FFF - 2000 * (freq_sys / 1000) / CAB_LSIFQ; | |||
|  |             if(((cnt_offset > -37 * (freq_sys / 1000) / 60000) && (cnt_offset < 37 * (freq_sys / 1000) / 60000)) || retry > 2) | |||
|  |             { | |||
|  |                 if(retry) | |||
|  |                     break; | |||
|  |             } | |||
|  |             retry++; | |||
|  |             cnt_offset = (cnt_offset > 0) ? (((cnt_offset * 2) / (74 * (freq_sys/1000) / 60000)) + 1) / 2 : (((cnt_offset * 2) / (74 * (freq_sys/1000) / 60000 )) - 1) / 2; | |||
|  |             sys_safe_access_enable(); | |||
|  |             R16_INT32K_TUNE += cnt_offset; | |||
|  |             sys_safe_access_disable(); | |||
|  |         } | |||
|  | 
 | |||
|  |         // 细调
 | |||
|  |         // 配置细调参数后,丢弃2次捕获值(软件行为)上判断已有一次,这里只留一次
 | |||
|  |         sys_safe_access_enable(); | |||
|  |         R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_TOTAL; | |||
|  |         R8_OSC_CAL_CTRL |= cali_Lv; | |||
|  |         sys_safe_access_disable(); | |||
|  |         while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_TOTAL) != cali_Lv ) | |||
|  |         { | |||
|  |             sys_safe_access_enable(); | |||
|  |             R8_OSC_CAL_CTRL |= cali_Lv; | |||
|  |             sys_safe_access_disable(); | |||
|  |         } | |||
|  | 
 | |||
|  |         sys_safe_access_enable(); | |||
|  |         R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN; | |||
|  |         R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |         R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |         R16_OSC_CAL_CNT |= RB_OSC_CAL_IF; | |||
|  |         sys_safe_access_disable(); | |||
|  |         while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 ) | |||
|  |         { | |||
|  |             sys_safe_access_enable(); | |||
|  |             R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |             sys_safe_access_disable(); | |||
|  |         } | |||
|  | 
 | |||
|  |         while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); // 用于丢弃
 | |||
|  | 
 | |||
|  |         SYS_DisableAllIrq(&irqv); | |||
|  |         sys_safe_access_enable(); | |||
|  |         R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN; | |||
|  |         R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |         R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |         R16_OSC_CAL_CNT |= RB_OSC_CAL_IF; | |||
|  |         sys_safe_access_disable(); | |||
|  |         while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 ) | |||
|  |         { | |||
|  |             sys_safe_access_enable(); | |||
|  |             R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN; | |||
|  |             sys_safe_access_disable(); | |||
|  |         } | |||
|  | 
 | |||
|  |         while(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT); | |||
|  |         cnt_32k = RTC_GetCycle32k(); | |||
|  |         while(RTC_GetCycle32k() == cnt_32k); | |||
|  |         R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR; | |||
|  |         SYS_RecoverIrq(irqv); | |||
|  |         while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); | |||
|  |         sys_safe_access_enable(); | |||
|  |         R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN; | |||
|  |         sys_safe_access_disable(); | |||
|  |         i = R16_OSC_CAL_CNT; // 实时校准后采样值
 | |||
|  |         cnt_offset = (i & 0x3FFF) + R8_OSC_CAL_OV_CNT * 0x3FFF -  4000 * (1 << cali_Lv) * (freq_sys / 1000000) / 256 * 1000/(CAB_LSIFQ/256); | |||
|  |         cnt_offset = (cnt_offset > 0) ? ((((cnt_offset * 2*(100 )) / (1366 * ((1 << cali_Lv)/8) * (freq_sys/1000) / 60000)) + 1) / 2) : ((((cnt_offset * 2*(100)) / (1366 * ((1 << cali_Lv)/8) * (freq_sys/1000) / 60000)) - 1) / 2); | |||
|  |         if((cnt_offset > 0)&&(((R16_INT32K_TUNE>>5)+cnt_offset)>0xFF)) | |||
|  |         { | |||
|  |             if(retry_all>2) | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R16_INT32K_TUNE |= (0xFF<<5); | |||
|  |                 sys_safe_access_disable(); | |||
|  |                 return; | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R16_INT32K_TUNE = (R16_INT32K_TUNE&0x1F)|(0x7F<<5); | |||
|  |                 sys_safe_access_disable(); | |||
|  |             } | |||
|  |         } | |||
|  |         else if((cnt_offset < 0)&&((R16_INT32K_TUNE>>5)<(-cnt_offset))) | |||
|  |         { | |||
|  |             if(retry_all>2) | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R16_INT32K_TUNE &= 0x1F; | |||
|  |                 sys_safe_access_disable(); | |||
|  |                 return; | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 sys_safe_access_enable(); | |||
|  |                 R16_INT32K_TUNE = (R16_INT32K_TUNE&0x1F)|(0x7F<<5); | |||
|  |                 sys_safe_access_disable(); | |||
|  |             } | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             sys_safe_access_enable(); | |||
|  |             R16_INT32K_TUNE += (cnt_offset<<5); | |||
|  |             sys_safe_access_disable(); | |||
|  |             return; | |||
|  |         } | |||
|  |         retry_all++; | |||
|  | 
 | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTCInitTime | |||
|  |  * | |||
|  |  * @brief   RTC时钟初始化当前时间 | |||
|  |  * | |||
|  |  * @param   y       - 配置年,MAX_Y = BEGYEAR + 44 | |||
|  |  * @param   mon     - 配置月,MAX_MON = 12 | |||
|  |  * @param   d       - 配置日,MAX_D = 31 | |||
|  |  * @param   h       - 配置小时,MAX_H = 23 | |||
|  |  * @param   m       - 配置分钟,MAX_M = 59 | |||
|  |  * @param   s       - 配置秒,MAX_S = 59 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_InitTime(uint16_t y, uint16_t mon, uint16_t d, uint16_t h, uint16_t m, uint16_t s) | |||
|  | { | |||
|  |     uint32_t         t; | |||
|  |     uint16_t         year, month, day, sec2, t32k; | |||
|  |     volatile uint8_t clk_pin; | |||
|  | 
 | |||
|  |     year = y; | |||
|  |     month = mon; | |||
|  |     day = 0; | |||
|  |     while(year > BEGYEAR) | |||
|  |     { | |||
|  |         day += YearLength(year - 1); | |||
|  |         year--; | |||
|  |     } | |||
|  |     while(month > 1) | |||
|  |     { | |||
|  |         day += monthLength(IsLeapYear(y), month - 2); | |||
|  |         month--; | |||
|  |     } | |||
|  | 
 | |||
|  |     day += d - 1; | |||
|  |     sec2 = (h % 24) * 1800 + m * 30 + s / 2; | |||
|  |     t32k = (s & 1) ? (0x8000) : (0); | |||
|  |     t = sec2; | |||
|  |     t = t << 16 | t32k; | |||
|  | 
 | |||
|  |     do | |||
|  |     { | |||
|  |         clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN); | |||
|  |     } while(clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN)); | |||
|  |     if(!clk_pin) | |||
|  |     { | |||
|  |         while(!clk_pin) | |||
|  |         { | |||
|  |             do | |||
|  |             { | |||
|  |                 clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN); | |||
|  |             } while(clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN)); | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R32_RTC_TRIG = day; | |||
|  |     R8_RTC_MODE_CTRL |= RB_RTC_LOAD_HI; | |||
|  |     sys_safe_access_disable(); | |||
|  |     while((R32_RTC_TRIG & 0x3FFF) != (R32_RTC_CNT_DAY & 0x3FFF)); | |||
|  |     sys_safe_access_enable(); | |||
|  |     R32_RTC_TRIG = t; | |||
|  |     R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_GetTime | |||
|  |  * | |||
|  |  * @brief   获取当前时间 | |||
|  |  * | |||
|  |  * @param   py      - 获取到的年,MAX_Y = BEGYEAR + 44 | |||
|  |  * @param   pmon    - 获取到的月,MAX_MON = 12 | |||
|  |  * @param   pd      - 获取到的日,MAX_D = 31 | |||
|  |  * @param   ph      - 获取到的小时,MAX_H = 23 | |||
|  |  * @param   pm      - 获取到的分钟,MAX_M = 59 | |||
|  |  * @param   ps      - 获取到的秒,MAX_S = 59 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_GetTime(uint16_t *py, uint16_t *pmon, uint16_t *pd, uint16_t *ph, uint16_t *pm, uint16_t *ps) | |||
|  | { | |||
|  |     uint32_t t; | |||
|  |     uint16_t day, sec2, t32k; | |||
|  | 
 | |||
|  |     day = R32_RTC_CNT_DAY & 0x3FFF; | |||
|  |     sec2 = R16_RTC_CNT_2S; | |||
|  |     t32k = R16_RTC_CNT_32K; | |||
|  | 
 | |||
|  |     t = sec2 * 2 + ((t32k < 0x8000) ? 0 : 1); | |||
|  | 
 | |||
|  |     *py = BEGYEAR; | |||
|  |     while(day >= YearLength(*py)) | |||
|  |     { | |||
|  |         day -= YearLength(*py); | |||
|  |         (*py)++; | |||
|  |     } | |||
|  | 
 | |||
|  |     *pmon = 0; | |||
|  |     while(day >= monthLength(IsLeapYear(*py), *pmon)) | |||
|  |     { | |||
|  |         day -= monthLength(IsLeapYear(*py), *pmon); | |||
|  |         (*pmon)++; | |||
|  |     } | |||
|  |     (*pmon)++; | |||
|  |     *pd = day + 1; | |||
|  |     *ph = t / 3600; | |||
|  |     *pm = t % 3600 / 60; | |||
|  |     *ps = t % 60; | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_SetCycle32k | |||
|  |  * | |||
|  |  * @brief   基于LSE/LSI时钟,配置当前RTC 周期数 | |||
|  |  * | |||
|  |  * @param   cyc     - 配置周期计数初值,MAX_CYC = 0xA8BFFFFF = 2831155199 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_SetCycle32k(uint32_t cyc) | |||
|  | { | |||
|  |     volatile uint8_t clk_pin; | |||
|  | 
 | |||
|  |     do | |||
|  |     { | |||
|  |         clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN); | |||
|  |     } while((clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN)) || (!clk_pin)); | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R32_RTC_TRIG = cyc; | |||
|  |     R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_GetCycle32k | |||
|  |  * | |||
|  |  * @brief   基于LSE/LSI时钟,获取当前RTC 周期数 | |||
|  |  * | |||
|  |  * @param   none | |||
|  |  * | |||
|  |  * @return  当前周期数,MAX_CYC = 0xA8BFFFFF = 2831155199 | |||
|  |  */ | |||
|  | __HIGH_CODE | |||
|  | uint32_t RTC_GetCycle32k(void) | |||
|  | { | |||
|  |     volatile uint32_t i; | |||
|  | 
 | |||
|  |     do | |||
|  |     { | |||
|  |         i = R32_RTC_CNT_32K; | |||
|  |     } while(i != R32_RTC_CNT_32K); | |||
|  | 
 | |||
|  |     return (i); | |||
|  | } | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_TMRFunCfg | |||
|  |  * | |||
|  |  * @brief   RTC定时模式配置(注意定时基准固定为32768Hz) | |||
|  |  * | |||
|  |  * @param   t   - refer to RTC_TMRCycTypeDef | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_TMRFunCfg(RTC_TMRCycTypeDef t) | |||
|  | { | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_RTC_MODE_CTRL &= ~(RB_RTC_TMR_EN | RB_RTC_TMR_MODE); | |||
|  |     sys_safe_access_disable(); | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_RTC_MODE_CTRL |= RB_RTC_TMR_EN | (t); | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_TRIGFunCfg | |||
|  |  * | |||
|  |  * @brief   RTC时间触发模式配置 | |||
|  |  * | |||
|  |  * @param   cyc - 相对当前时间的触发间隔时间,基于LSE/LSI时钟周期数 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_TRIGFunCfg(uint32_t cyc) | |||
|  | { | |||
|  |     uint32_t t; | |||
|  | 
 | |||
|  |     t = RTC_GetCycle32k() + cyc; | |||
|  |     if(t > RTC_MAX_COUNT) | |||
|  |     { | |||
|  |         t -= RTC_MAX_COUNT; | |||
|  |     } | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R32_RTC_TRIG = t; | |||
|  |     R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN; | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_ModeFunDisable | |||
|  |  * | |||
|  |  * @brief   RTC 模式功能关闭 | |||
|  |  * | |||
|  |  * @param   m   - 需要关闭的当前模式 | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_ModeFunDisable(RTC_MODETypeDef m) | |||
|  | { | |||
|  |     uint8_t i = 0; | |||
|  | 
 | |||
|  |     if(m == RTC_TRIG_MODE) | |||
|  |     { | |||
|  |         i |= RB_RTC_TRIG_EN; | |||
|  |     } | |||
|  |     else if(m == RTC_TMR_MODE) | |||
|  |     { | |||
|  |         i |= RB_RTC_TMR_EN; | |||
|  |     } | |||
|  | 
 | |||
|  |     sys_safe_access_enable(); | |||
|  |     R8_RTC_MODE_CTRL &= ~(i); | |||
|  |     sys_safe_access_disable(); | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_GetITFlag | |||
|  |  * | |||
|  |  * @brief   获取RTC中断标志 | |||
|  |  * | |||
|  |  * @param   f   - refer to RTC_EVENTTypeDef | |||
|  |  * | |||
|  |  * @return  中断标志状态 | |||
|  |  */ | |||
|  | uint8_t RTC_GetITFlag(RTC_EVENTTypeDef f) | |||
|  | { | |||
|  |     if(f == RTC_TRIG_EVENT) | |||
|  |     { | |||
|  |         return (R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG); | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         return (R8_RTC_FLAG_CTRL & RB_RTC_TMR_FLAG); | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | /*********************************************************************
 | |||
|  |  * @fn      RTC_ClearITFlag | |||
|  |  * | |||
|  |  * @brief   清除RTC中断标志 | |||
|  |  * | |||
|  |  * @param   f   - refer to RTC_EVENTTypeDef | |||
|  |  * | |||
|  |  * @return  none | |||
|  |  */ | |||
|  | void RTC_ClearITFlag(RTC_EVENTTypeDef f) | |||
|  | { | |||
|  |     switch(f) | |||
|  |     { | |||
|  |         case RTC_TRIG_EVENT: | |||
|  |             R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR; | |||
|  |             break; | |||
|  |         case RTC_TMR_EVENT: | |||
|  |             R8_RTC_FLAG_CTRL = RB_RTC_TMR_CLR; | |||
|  |             break; | |||
|  |         default: | |||
|  |             break; | |||
|  |     } | |||
|  | } |