当前位置:网站首页>Gd32 RT thread RTC driver function
Gd32 RT thread RTC driver function
2022-06-30 10:34:00 【Sky_ Lannister】
GD32 RTC Driving functions
The driver function needs to modify two files ,drv_rtc.c, Use RT_USING_RTC Open and close , For transplant precautions, see Migrate full version RT-Thread To GD32F4XX( detailed ) About China rtc Migration related content , The use and verification methods after transplantation are the same as stm32
drv_rtc.c
/** ****************************************************************************** * @file drv_rtc.c * @author yangFei * @brief according to GD32 Library implementation RTC drive * * @version V1.0.0 * @date 2022.06.24 * @verbatim * * @endverbatim ****************************************************************************** * @note For before RT-Thread Team Of iysheng To write , But it doesn't apply F4XX series * @attention * * Change Logs: * Date Author Notes * 2022-01-25 iysheng first version * 2022.06.24 yangFei Applicable chips are GD32f4xx, Use the official standard library , Routines are ported from https://github.com/RT-Thread/rt-thread/tree/master/bsp/gd32/gd32407v-start * ****************************************************************************** */
#include <sys/time.h>
#define DBG_TAG "drv.rtc"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_RTC
#define RTC_CLOCK_SOURCE_LXTAL 1
__IO uint32_t prescaler_a = 0, prescaler_s = 0;
typedef struct {
struct rt_device rtc_dev;
} gd32_rtc_device;
static gd32_rtc_device g_gd32_rtc_dev;
static time_t get_rtc_timestamp(void)
{
rtc_parameter_struct rtc_timestamp = {
0}; //add by yf
struct tm tm_new = {
0};
rtc_current_time_get(&rtc_timestamp);
tm_new.tm_sec = rtc_timestamp.second;
tm_new.tm_min = rtc_timestamp.minute;
tm_new.tm_hour = rtc_timestamp.hour;
tm_new.tm_mday = rtc_timestamp.date;
tm_new.tm_mon = rtc_timestamp.month - 1;
tm_new.tm_year = rtc_timestamp.year + 100;
LOG_D("get rtc time.");
return mktime(&tm_new);
}
static rt_err_t set_rtc_timestamp(time_t time_stamp)
{
rtc_parameter_struct rtc_initpara;
struct tm *p_tm;
p_tm = localtime(&time_stamp);
if (p_tm->tm_year < 100)
{
return -RT_ERROR;
}
rtc_initpara.factor_asyn = prescaler_a;
rtc_initpara.factor_syn = prescaler_s;
rtc_initpara.display_format = RTC_24HOUR;
rtc_initpara.am_pm = RTC_AM;
rtc_initpara.second = p_tm->tm_sec ;
rtc_initpara.minute = p_tm->tm_min ;
rtc_initpara.hour = p_tm->tm_hour;
rtc_initpara.date = p_tm->tm_mday;
rtc_initpara.month = p_tm->tm_mon + 1 ;
rtc_initpara.year = p_tm->tm_year - 100;
rtc_initpara.day_of_week = p_tm->tm_wday + 1;
if (rtc_init(&rtc_initpara) == ERROR)
{
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t rt_gd32_rtc_control(rt_device_t dev, int cmd, void *args)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
*(rt_uint32_t *)args = get_rtc_timestamp();
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
if (set_rtc_timestamp(*(rt_uint32_t *)args))
{
result = -RT_ERROR;
}
break;
}
return result;
}
#ifdef RT_USING_DEVICE_OPS // There is no definition
const static struct rt_device_ops g_gd32_rtc_ops =
{
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
rt_gd32_rtc_control
};
#endif
static int rt_hw_rtc_init(void)
{
rt_err_t ret;
time_t rtc_counter;
rcu_periph_clock_enable(RCU_PMU);
pmu_backup_write_enable();
rcu_periph_clock_enable(RCU_BKPSRAM);//bug RCU_BKPI - RCU_BKPSRAM
rtc_counter = get_rtc_timestamp();
/* once the rtc clock source has been selected, if can't be changed * anymore unless the Backup domain is reset */
rcu_bkp_reset_enable();
rcu_bkp_reset_disable();
#if RTC_CLOCK_SOURCE_IRC32K
rcu_osci_on(RCU_IRC32K);
if (SUCCESS == rcu_osci_stab_wait(RCU_IRC32K))
{
rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
}
prescaler_s = 0x13F;
prescaler_a = 0x63;
#elif RTC_CLOCK_SOURCE_LXTAL
rcu_osci_on(RCU_LXTAL);
if (SUCCESS == rcu_osci_stab_wait(RCU_LXTAL))
{
/* set lxtal as rtc clock source */
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
}
prescaler_s = 0xFF;
prescaler_a = 0x7F;
#else
LOG_E("RTC clock source should be defined");
#endif /* RTC_CLOCK_SOURCE_IRC32K */
rcu_periph_clock_enable(RCU_RTC);
rtc_register_sync_wait();
set_rtc_timestamp(rtc_counter);
#ifdef RT_USING_DEVICE_OPS
g_gd32_rtc_dev.rtc_dev.ops = &g_gd32_rtc_ops;
#else
g_gd32_rtc_dev.rtc_dev.init = RT_NULL;
g_gd32_rtc_dev.rtc_dev.open = RT_NULL;
g_gd32_rtc_dev.rtc_dev.close = RT_NULL;
g_gd32_rtc_dev.rtc_dev.read = RT_NULL;
g_gd32_rtc_dev.rtc_dev.write = RT_NULL;
g_gd32_rtc_dev.rtc_dev.control = rt_gd32_rtc_control;
#endif
g_gd32_rtc_dev.rtc_dev.type = RT_Device_Class_RTC;
g_gd32_rtc_dev.rtc_dev.rx_indicate = RT_NULL;
g_gd32_rtc_dev.rtc_dev.tx_complete = RT_NULL;
g_gd32_rtc_dev.rtc_dev.user_data = RT_NULL;
ret = rt_device_register(&g_gd32_rtc_dev.rtc_dev, "rtc", \
RT_DEVICE_FLAG_RDWR);
if (ret != RT_EOK)
{
LOG_E("failed register internal rtc device, err=%d", ret);
}
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
#endif
/************************ (C) COPYRIGHT *****END OF FILE****/
gd32f4xx_rtc.c
// No major modification , Only on rtc_init And rtc_current_time_get The passed in parameters in are byte and BCD Code to code operation , The definition of time in the register uses BCD Code format
/** * @brief Convert a 2 digit decimal to BCD format. * @param Value Byte to be converted * @retval Converted byte */
uint8_t RTC_ByteToBcd2(uint8_t Value)
{
uint32_t bcdhigh = 0U;
uint8_t temp = Value;
while (temp >= 10U)
{
bcdhigh++;
temp -= 10U;
}
return ((uint8_t)(bcdhigh << 4U) | temp);
}
/** * @brief Convert from 2 digit BCD to Binary. * @param Value BCD value to be converted * @retval Converted word */
uint8_t RTC_Bcd2ToByte(uint8_t Value)
{
uint8_t tmp;
tmp = ((Value & 0xF0U) >> 4U) * 10U;
return (tmp + (Value & 0x0FU));
}
ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
{
ErrStatus error_status = ERROR;
uint32_t reg_time = 0U, reg_date = 0U;
reg_date = (DATE_YR(RTC_ByteToBcd2(rtc_initpara_struct->year)) | \
DATE_DOW(rtc_initpara_struct->day_of_week) | \
DATE_MON(RTC_ByteToBcd2(rtc_initpara_struct->month)) | \
DATE_DAY(RTC_ByteToBcd2(rtc_initpara_struct->date)));
reg_time = (rtc_initpara_struct->am_pm| \
TIME_HR(RTC_ByteToBcd2(rtc_initpara_struct->hour)) | \
TIME_MN(RTC_ByteToBcd2(rtc_initpara_struct->minute)) | \
TIME_SC(RTC_ByteToBcd2(rtc_initpara_struct->second)));
/* 1st: disable the write protection */
RTC_WPK = RTC_UNLOCK_KEY1;
RTC_WPK = RTC_UNLOCK_KEY2;
/* 2nd: enter init mode */
error_status = rtc_init_mode_enter();
if(ERROR != error_status){
RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \
PSC_FACTOR_S(rtc_initpara_struct->factor_syn));
RTC_TIME = (uint32_t)reg_time;
RTC_DATE = (uint32_t)reg_date;
RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
RTC_CTL |= rtc_initpara_struct->display_format;
/* 3rd: exit init mode */
rtc_init_mode_exit();
/* 4th: wait the RSYNF flag to set */
error_status = rtc_register_sync_wait();
}
/* 5th: enable the write protection */
RTC_WPK = RTC_LOCK_KEY;
return error_status;
}
void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
{
uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U;
temp_tr = (uint32_t)RTC_TIME;
temp_dr = (uint32_t)RTC_DATE;
temp_pscr = (uint32_t)RTC_PSC;
temp_ctlr = (uint32_t)RTC_CTL;
/* get current time and construct rtc_parameter_struct structure */
rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr);
rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr);
rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr);
rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);
rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr);
rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr);
rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr);
rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
rtc_initpara_struct->am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM);
rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
/* Convert the time structure parameters to Binary format */
rtc_initpara_struct->year = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->year);
rtc_initpara_struct->month = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->month);
rtc_initpara_struct->date = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->date);
rtc_initpara_struct->hour = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->hour);
rtc_initpara_struct->minute = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->minute);
rtc_initpara_struct->second = (uint8_t)RTC_Bcd2ToByte(rtc_initpara_struct->second);
}
边栏推荐
- 从0使用keil5软件仿真调试GD32F305
- 最新SCI影响因子公布:国产期刊最高破46分!网友:算是把IF玩明白了
- Koreano essential creates a professional style
- Configure Yii: display MySQL extension module verification failed
- MySQL advanced SQL statement of database (1)
- Memorize the text and remember the words. Read the text and remember the words. Read the article and remember the words; 40 articles with 3500 words; 71 articles broke through the words in the middle
- The famous painter shiguoliang's "harvest season" digital collection was launched on the Great Wall Digital Art
- Curl --- the request fails when the post request parameter is too long (more than 1024b)
- Ant s19xp appeared in 140t, why is it called the computing power ceiling by the world
- Who should the newly admitted miners bow to in front of the chip machine and the graphics card machine
猜你喜欢

Koreano essential creates a professional style

著名画家史国良《丰收时节》数字藏品上线长城数艺

How to seize the opportunity of NFT's "chaos"?
[email protected]语音模块+stm32+nfc"/>技能梳理[email protected]语音模块+stm32+nfc

MySQL log management, backup and recovery of databases (1)

KOREANO ESSENTIAL打造气质职场范
[email protected] intelligent instrument teaching aids based on 51 series single chip microcomputer"/>Skill combing [email protected] intelligent instrument teaching aids based on 51 series single chip microcomputer

ArcGIS Pro scripting tool (6) -- repairing CAD layer data sources

The performance of arm's new CPU has been improved by 22%, up to 12 cores can be combined, and the GPU is first equipped with hardware optical tracking. Netizen: the gap with apple is growing

JS obtient la chaîne spécifiée spécifiant la position du caractère & sous - chaîne spécifiant la plage de position du caractère 【 détails simples 】
随机推荐
RobotFramework学习笔记:环境安装以及robotframework-browser插件的安装
Chen Haotian won the national championship of the national finals of the 7th children's model star ceremony
mysql数据库基础:约束、标识列
乡村振兴公益基金启动暨古茶树非遗保护公益行发布
【Rust日报】2021-01-22 首份Rust月刊杂志邀请大家一起参与
R语言aov函数进行重复测量方差分析(Repeated measures ANOVA、其中一个组内因素和一个组间因素)、分别使用interaction.plot函数和boxplot对交互作用进行可视化
Great Wall digital art digital collection platform releases the creation Badge
技能梳理[email protected]體感機械臂
Skill sorting [email protected]+ Alibaba cloud +nbiot+dht11+bh1750+ soil moisture sensor +oled
Go -- standard library sort package
移植完整版RT-Thread到GD32F4XX(详细)
Highlight display of Jinbei LB box, adhering to mini special effects
ArcGIS Pro + PS 矢量化用地规划图
R language plot visualization: use plot to visualize the prediction confidence of the multi classification model, the prediction confidence of each data point of the model in the 2D grid, and the conf
ArcGIS PRO + PS vectorized land use planning map
Memorize the text and remember the words. Read the text and remember the words. Read the article and remember the words; 40 articles with 3500 words; 71 articles broke through the words in the middle
How to deploy deflationary combustion destruction contract code in BSC chain_ Deploy dividend and marketing wallet contract code
著名画家史国良《丰收时节》数字藏品上线长城数艺
keras ‘InputLayer‘ object is not iterable
Harvester ch1 of CKB and HNS, connection tutorial analysis