CIU32_L051_M307R/bsp/src/bsp_rtc.c

394 lines
10 KiB
C
Raw Normal View History

#include "bsp_rtc.h"
2024-09-02 16:09:03 +08:00
2024-08-23 14:07:32 +08:00
/* 时钟精度ppm值根据实测RTC时钟精度填写 */
#define FRTC_PPM (-20L)
#define TIMES_TO_GET_TR (0x03) /* 两次读日历不一致后再次循环次数 */
2024-08-23 14:07:32 +08:00
/**
* @brief RTC中断服务函数
* @retval
*/
void RTC_TAMP_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
/* 校准周期中断处理流程 */
if (std_rtc_get_calib_interrupt_enable() && std_rtc_get_interrupt_flag(RTC_INTERRUPT_FLAG_CALIBRATION))
{
/* 清除校准周期标志 */
std_rtc_clear_flag(RTC_CLEAR_CALIBRATION);
}
/* TAMP IN中断处理流程 */
if (std_tamp_get_interrupt_enable(TAMP_INTERRUPT_TAMP_IN) && std_tamp_get_interrupt_flag(TAMP_INTERRUPT_FLAG_TAMP_IN))
{
/* 清除外部入侵检测(外部引脚)的标志 */
std_tamp_clear_flag(TAMP_CLEAR_FLAG_TAMP_IN);
}
/* 闹钟中断处理流程 */
if (std_rtc_get_alarm_interrupt_enable() && std_rtc_get_interrupt_flag(RTC_INTERRUPT_FLAG_ALARM))
{
/* 清除闹钟标志 */
std_rtc_clear_flag(RTC_CLEAR_ALARM);
}
2024-09-02 16:09:03 +08:00
/* 周期中断处理流程 */
if (std_rtc_get_wut_interrupt_enable(RTC_WUT_INTERRUPT_MIN) && std_rtc_get_interrupt_flag(RTC_INTERRUPT_FLAG_MIN))
2024-08-23 14:07:32 +08:00
{
2024-09-02 16:09:03 +08:00
/* 清除周期中断标志 */
std_rtc_clear_flag(RTC_INTERRUPT_FLAG_MIN);
2024-08-23 14:07:32 +08:00
}
/* leave interrupt */
rt_interrupt_leave();
}
/**
* @brief RTC日期时间配置
* @retval BCD输入
*/
2024-09-02 16:09:03 +08:00
void BSP_Rtc_DateTime_Cfg(uint8_t years, uint8_t months, uint8_t days, uint8_t hour, uint8_t minute, uint8_t second, uint8_t week)
2024-08-23 14:07:32 +08:00
{
std_rtc_time_t rtc_time = {0};
std_rtc_date_t rtc_date = {0};
std_status_t status = STD_ERR;
/* RTC日期BCD码初始化 */
// rtc_date.weekday = RTC_WEEKDAY_FRIDAY;
// rtc_date.month = RTC_MONTH_AUGUST;
rtc_date.weekday = week;
rtc_date.month = months;
rtc_date.day = days;
rtc_date.year = years;
status = std_rtc_date_init(&rtc_date);
while (status != STD_OK)
{
/* RTC日期初始化失败处理代码 */
}
/* RTC时间BCD码初始化 */
rtc_time.hours = hour;
rtc_time.minutes = minute;
rtc_time.seconds = second;
status = std_rtc_time_init(&rtc_time);
while (status != STD_OK)
{
/* RTC时间初始化失败处理代码 */
}
}
MSH_CMD_EXPORT(BSP_Rtc_DateTime_Cfg, " BCD格式输入 RTC日期时间配置:y,m,d,h,m,s,w ");
/**
* @brief RTC_OUT输出信号配置
* @retval
*/
void BSP_Rtc_OutPut_Config(void)
{
/* 关闭RTC寄存器写保护 */
std_rtc_write_protection_disable();
/* 配置RTC_OUT输出1Hz */
std_rtc_out_config(RTC_OUTPUT_SPRE_1HZ);
/* 配置RTC_OUT输出使能 */
std_rtc_output_enable();
/* 使能RTC寄存器写保护 */
std_rtc_write_protection_enable();
}
/**
* @brief RTC_OUT输出信号配置
* @retval
*/
void BSP_Rtc_Output_Cfg(void)
{
/* 配置RTC_OUT输出1Hz */
std_rtc_out_config(RTC_OUTPUT_SPRE_1HZ);
/* 配置RTC_OUT输出使能 */
std_rtc_output_enable();
}
/**
* @brief TAMP IN配置
* @retval
*/
void bsp_rtc_tamp_in_config(void)
{
/* 关闭RTC寄存器写保护 */
std_rtc_write_protection_disable();
/* 关闭RTC_OUT信号输出 */
std_rtc_output_disable();
/* RTC寄存器写保护使能 */
std_rtc_write_protection_enable();
/* 禁止外部入侵检测 */
std_tamp_disable(TAMP_SOURCE_TAMP_IN);
/* 设置入侵检测触发方式 */
std_tamp_set_trigger(TAMP_TRIGGER_FALLING_EDGE);
/* 设置入侵检测引脚数字滤波参数 */
std_tamp_set_filter(TAMP_FILTER_DISABLE);
/* 使能入侵检测引脚上拉电阻 */
std_tamp_pullup_enable();
/* 使能外部入侵检测中断 */
std_tamp_interrupt_enable(TAMP_INTERRUPT_TAMP_IN);
/* 使能外部入侵检测 */
std_tamp_enable(TAMP_SOURCE_TAMP_IN);
/* 配置中断优先级 */
NVIC_SetPriority(RTC_TAMP_IRQn, NVIC_PRIO_0);
/* 使能中断 */
NVIC_EnableIRQ(RTC_TAMP_IRQn);
}
/**
* @brief RTC闹钟配置
* @retval
*/
void BSP_Rtc_Alarm_Config(uint8_t hours, uint8_t minutes, uint8_t seconds)
{
std_rtc_alarm_t rtc_alarm = {0};
/* 禁止闹钟 */
std_rtc_write_protection_disable();
std_rtc_alarm_disable();
std_rtc_write_protection_enable();
/* 闹钟初始化 */
rtc_alarm.time.hours = std_rtc_convert_bin2bcd(hours);
rtc_alarm.time.minutes = std_rtc_convert_bin2bcd(minutes);
rtc_alarm.time.seconds = std_rtc_convert_bin2bcd(seconds);
rtc_alarm.time_mask = RTC_ALARM_MASK_NONE;
std_rtc_alarm_init(&rtc_alarm);
/* 使能闹钟,开启闹钟中断 */
std_rtc_write_protection_disable();
std_rtc_alarm_interrupt_enable();
std_rtc_alarm_enable();
std_rtc_write_protection_enable();
/* 配置中断优先级 */
NVIC_SetPriority(RTC_TAMP_IRQn, NVIC_PRIO_0);
/* 使能中断 */
NVIC_EnableIRQ(RTC_TAMP_IRQn);
}
/**
2024-09-02 16:09:03 +08:00
* @brief RTC唤醒定时器配置
* @retval
*/
2024-08-23 14:07:32 +08:00
void BSP_Rtc_Wakeup_Config(void)
{
/* 关闭RTC寄存器写保护 */
std_rtc_write_protection_disable();
2024-09-02 16:09:03 +08:00
/* 使能分钟周期定时中断 */
std_rtc_wut_interrupt_enable(RTC_WUT_INTERRUPT_MIN);
2024-08-23 14:07:32 +08:00
/* 使能RTC寄存器写保护 */
std_rtc_write_protection_enable();
2024-09-02 16:09:03 +08:00
2024-08-23 14:07:32 +08:00
/* 配置中断优先级 */
2024-09-02 16:09:03 +08:00
NVIC_SetPriority(RTC_TAMP_IRQn, NVIC_PRIO_0);
2024-08-23 14:07:32 +08:00
/* 使能中断 */
2024-09-02 16:09:03 +08:00
NVIC_EnableIRQ(RTC_TAMP_IRQn);
2024-08-23 14:07:32 +08:00
}
/**
2024-09-02 16:09:03 +08:00
* @brief 使PMU低功耗配置
* @retval
*/
2024-08-23 14:07:32 +08:00
void BSP_Pmu_LowPower_Config(void)
{
std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_PMU);
2024-09-02 16:09:03 +08:00
2024-08-23 14:07:32 +08:00
/* 使能超低功耗配置 */
2024-09-02 16:09:03 +08:00
std_pmu_ultra_lowpower_enable();
2024-08-23 14:07:32 +08:00
}
/**
* @brief
* @param rtcdate
* @param rtctime
* @retval
*/
void BSP_Rtc_Get_Calendar(uint8_t *rtcdate, uint8_t *rtctime)
{
uint32_t i, read_ok = 0;
uint32_t temp_time1 = 0, temp_time2 = 0;
uint32_t temp_date1 = 0, temp_date2 = 0;
/* 读取日历 */
for (i = 0; i < TIMES_TO_GET_TR; i++)
{
/* 读一次日历时间 */
temp_time1 = std_rtc_time_get_time();
temp_date1 = std_rtc_date_get_date();
/* 再读一次日历时间 */
temp_time2 = std_rtc_time_get_time();
temp_date2 = std_rtc_date_get_date();
/* 连续两次读取结果比对 */
if ((temp_time1 == temp_time2) && (temp_date1 == temp_date2))
{
/* 两者一致,表示读取成功 */
read_ok = 1;
break;
}
}
/* 时间读取正确 */
if (read_ok)
{
/* 获取时间 */
rtctime[0] = (temp_time1 >> RTC_OFFSET_HOUR) & 0xFF;
rtctime[1] = (temp_time1 >> RTC_OFFSET_MINUTE) & 0xFF;
rtctime[2] = temp_time1 & 0xFF;
/* 获取日期 */
rtcdate[0] = (temp_date1 >> RTC_OFFSET_YEAR) & 0xFF;
rtcdate[1] = (temp_date1 >> RTC_OFFSET_MONTH) & 0xFF;
rtcdate[2] = temp_date1 & 0xFF;
}
/* 时间读取不正确 */
else
{
while (1)
{
/* 时间读取不正确处理代码 */
}
}
}
/**
* @brief
* @param timestamp_date
* @param timestamp_time
* @retval
*/
void BSP_Rtc_Get_Timestamp(uint8_t *timestamp_date, uint8_t *timestamp_time)
{
/* 等待时间戳标志TSF置1 */
while (!std_rtc_get_flag(RTC_FLAG_TIMESTAMP));
/* 读取时间戳时间 */
timestamp_time[0] = std_rtc_timestamp_get_hour();
timestamp_time[1] = std_rtc_timestamp_get_minute();
timestamp_time[2] = std_rtc_timestamp_get_second();
/* 读取时间戳日期 */
timestamp_date[0] = std_rtc_timestamp_get_day();
timestamp_date[1] = std_rtc_timestamp_get_month();
/* 清除时间戳标志 */
std_rtc_clear_flag(RTC_CLEAR_TIMESTAMP);
}
/**
* @brief RTC时钟数字平滑校准参数
* @param calib_plus_pulses
* @arg RTC_SMOOTH_CALIB_PLUS_PULSES_RESET
* @arg RTC_SMOOTH_CALIB_PLUS_PULSES_SET
* @param calib_minus_pulses
* @retval
*/
void BSP_Rtc_Calib_Cfg(uint32_t calib_plus_pulses, uint32_t calib_minus_pulses)
{
/* 开启校准周期中断 */
std_rtc_calib_interrupt_enable();
/* 配置数字平滑校准参数 */
while (std_rtc_cal_get_status());
std_rtc_cal_config(calib_plus_pulses, calib_minus_pulses);
/* 配置中断优先级 */
NVIC_SetPriority(RTC_TAMP_IRQn, NVIC_PRIO_0);
/* 使能中断 */
NVIC_EnableIRQ(RTC_TAMP_IRQn);
}
/**
* @brief RTC时钟设置 RTC在VCORE_AON域使VCORE_AON复位清除所有寄存器状态
* @retval
*/
void rtc_clock_config(void)
{
/* RTC APB时钟使能 */
std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_RTC);
/* 使能PMU时钟开启VCORE_AON写使能 */
std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_PMU);
std_pmu_vaon_write_enable();
/* 使能LXTAL时钟 */
std_rcc_lxtal_drive_mode_config(RCC_LXTAL_DRIVE_MODE_ENHANCE);
std_rcc_lxtal_drive_config(RCC_LXTAL_DRIVE_LEVEL2);
std_rcc_lxtal_enable(RCC_LXTAL_ON);
while (!std_rcc_get_lxtal_ready());
/* 选择LXTAL作为RTC时钟源
: RTC时钟源后RTC时钟源
- VCORE_AON域复位
*/
std_rcc_set_rtcclk_source(RCC_RTC_ASYNC_CLK_SRC_LXTAL);
/* RTC外设时钟使能 */
std_rcc_rtc_enable();
}
int BSP_RTC_Init(void)
{
float calp_val = 0, calm_val = 0;
/* RTC时钟源选择LXTAL */
rtc_clock_config();
/* RTC在VCORE_AON域可使用VCORE_AON复位清除所有寄存器状态 */
/* 关闭RTC寄存器写保护 */
std_rtc_write_protection_disable();
/* RTC_OUT输出预分频的时钟信号1Hz */
BSP_Rtc_Output_Cfg();
/* 等待3s */
rt_thread_mdelay(3000);
if (FRTC_PPM > 0)
{
calp_val = RTC_SMOOTH_CALIB_PLUS_PULSES_RESET;
calm_val = FRTC_PPM / 0.954 + 0.5;
}
else if (FRTC_PPM < 0)
{
calp_val = RTC_SMOOTH_CALIB_PLUS_PULSES_SET;
calm_val = (512 + (FRTC_PPM / 0.954) + 0.5);
}
/* 设置校准参数 */
BSP_Rtc_Calib_Cfg((uint32_t)calp_val, (uint32_t)calm_val);
/* 使能RTC寄存器写保护 */
std_rtc_write_protection_enable();
/* RTC日期时间配置 */
BSP_Rtc_DateTime_Cfg(0x24, 0x08, 0x23, 0x14, 0x03, 0x05, 0x05);
2024-09-02 16:09:03 +08:00
2024-08-23 14:07:32 +08:00
return RT_EOK;
}
INIT_PREV_EXPORT(BSP_RTC_Init);