当前位置:网站首页>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);
}
边栏推荐
- “昆明城市咖啡地圖”活動再度開啟
- “昆明城市咖啡地图”再度开启,咖啡拉近城市距离
- 华南产业集团发力数字经济,城链科技发布会成功召开
- Compétences Comb 27 @ Body sense Manipulator
- ArcGIS Pro脚本工具(6)——修复CAD图层数据源
- 透过华为军团看科技之变(五):智慧园区
- Nlopt -- Nonlinear Optimization -- principle introduction and application method
- 孙安民作品《莲花净心》数字藏品上线长城数艺
- 郭琳加冕 2022第三季完美大师 全球人气季军
- MIT-6874-Deep Learning in the Life Sciences Week5
猜你喜欢

Dyson design award, changing the world with sustainable design

Koreano essential creates a professional style

苹果5G芯片被曝研发失败,QQ密码bug引热议,蔚来回应做空传闻,今日更多大新闻在此...

《锦绣中华》中老年公益文旅游-走进佛山敬老院
![JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]](/img/01/6829e85bf28431eb06e70b87ceaaff.jpg)
JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]

“昆明城市咖啡地图”活动再度开启

Test memory read rate

Action bright: take good care of children's eyes together -- a summary of the field investigation on the implementation of action bright in Guangxi

Configure Yii: display MySQL extension module verification failed

Arm新CPU性能提升22%,最高可组合12核,GPU首配硬件光追,网友:跟苹果的差距越来越大了...
随机推荐
“昆明城市咖啡地圖”活動再度開啟
技能梳理[email protected]+阿里云+nbiot+dht11+bh1750+土壤湿度传感器+oled
Go -- standard library sort package
Yixian e - commerce publie un rapport trimestriel: adhérer à la R & D et à l’investissement de la marque, réaliser un développement durable et de haute qualité
ArcGIS Pro + PS 矢量化用地规划图
CVPR 2022 | Tsinghua & bytek & JD put forward BRT: Bridging Transformer for vision and point cloud 3D target detection
JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]
Curl --- the request fails when the post request parameter is too long (more than 1024b)
著名画家史国良《丰收时节》数字藏品上线长城数艺
ArcGIS Pro scripting tool (5) - delete duplicates after sorting
【Rust日报】2021-01-23 几个新库发布
那个程序员,被打了。
Implementation of iterative method for linear equations
AttributeError: ‘Version‘ object has no attribute ‘major‘
潘多拉 IOT 开发板学习(HAL 库)—— 实验1 跑马灯(RGB)实验(学习笔记)
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
Chen Haotian won the national championship of the national finals of the 7th children's model star ceremony
新冠无情人有情,芸众惠爱心善举暖人间——捐赠商丘市儿童福利院公益行动
技能梳理[email protected]在oled上控制一条狗的奔跑
Harvester ch1 of CKB and HNS, connection tutorial analysis