GD32 RTC驱动函数

驱动函数需要修改两个文件,drv_rtc.c,使用RT_USING_RTC进行开启关闭,移植注意事项参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于rtc移植相关内容,移植完成后使用及验证方法同stm32

drv_rtc.c

/********************************************************************************* @file    drv_rtc.c* @author  yangFei* @brief   按照GD32库实现RTC驱动** @version V1.0.0* @date    2022.06.24* @verbatim** @endverbatim******************************************************************************* @note  之前为RT-Thread Team的iysheng编写,但是不适用于F4XX系列* @attention** Change Logs:* Date           Author       Notes* 2022-01-25     iysheng      first version* 2022.06.24     yangFei      适用芯片为GD32f4xx,使用官方提供标准库,例程移植自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 yfstruct 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  //暂无定义
const static struct rt_device_ops g_gd32_rtc_ops =
{RT_NULL,RT_NULL,RT_NULL,RT_NULL,RT_NULL,rt_gd32_rtc_control
};
#endifstatic 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_BKPSRAMrtc_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_IRC32Krcu_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_LXTALrcu_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;#elseLOG_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_OPSg_gd32_rtc_dev.rtc_dev.ops         = &g_gd32_rtc_ops;
#elseg_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;
#endifg_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

//未做大修改,仅对rtc_init及rtc_current_time_get中的传入参数做了字节和BCD码互转的操作,寄存器中关于时间的定义使用BCD码格式/*** @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);
}

GD32 RT-Thread RTC驱动函数相关推荐

  1. xpt 2046的触摸屏 rt thread设备驱动框架

    1 基于rtt 开发触摸屏驱动 准备使用rtt 框架 , 驱动xpt 2046的触摸屏, 翻阅大量资料发现, 大部分文章强调的是时序图, 而且很多代码要么直接操作寄存器, 要么是io 口模拟, 只能用 ...

  2. GD32 RT-Thread OTA/Bootloader驱动函数

    GD32 OTA/Bootloader驱动函数 驱动函数需要修改一个文件rt_fota.c,添加内部flash操作相关文件,删除外部flash操作相关文件,移植过程注意事项及其它外设移植细节参见 移植 ...

  3. 正点原子delay函数移植到rt thread操作系统(HAL库)

    正点原子教程中涉及到的操作系统只涉及了UCOS的教程,其中例程的system文件夹中的delay.c函数只是适配了UCOS. 下面将delay.c函数移植到rt thread中,使用的bsp是rt t ...

  4. rt thread studio使用QBOOT和片外flash实现OTA升级

    我们这里要使用单片机外部flash作为OTA的下载分区,外部flash硬件连接关系 PB3-->SPI3_CLK PB4-->SPI3_MISO PB5-->SPI3_MOSI PE ...

  5. RT Thread根据开发板制作BSP方法

    之前一直不懂怎么使用RT Thread的软件包,感谢网上的大神,看了你们的博客后大概了解一些,在此做下记录.用RT Thread软件包需要RT Thread的系统,但是RT Thread和RT Thr ...

  6. 基于rt thread smart构建EtherCAT主站

    我把源码开源到到了gitee,https://gitee.com/rathon/rt-thread-smart-soem 有兴趣的去可以下载下来跑一下 软件工程推荐用vscode 打开.rt thre ...

  7. stm32f407单片机rt thread 片外spi flash OTA升级配置示例

    参考地址https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/ 第一步,生成Boot ...

  8. linux下测试RTC驱动相关的命令date和hwclock常见用法简介

    之前对Linux下面时间相关的内容,一无所知,第一次见到hwclock,不知为何物,也没找到解释清楚的帖子.故此整理一下,简单介绍Linux下验证rtc驱动是否工作正常,相关的的命令:date和hwc ...

  9. rtems 4.11 RTC驱动 (arm, beagle)

    RTC驱动的框架在 c/src/lib/libbsp/shared/tod.c 中,大部分功能都已经实现了,入口函数是 rtc_initialize(),BSP要实现的东西非常少. beagle的实现 ...

最新文章

  1. python2和python3区别
  2. oracle增加数据时报没安装java_在linux上安装Oracle Developer Tools for VS Code
  3. 15:18 2009-7-5 小结
  4. oracle 从dbf恢复,oracle 误删 dbf 恢复
  5. Build Docker image of a Python Flask app【转载】
  6. class.forname()中要写相对路径吗?_你喜欢这里吗?翻译成“Do you like here?”是错误的,为啥呢?...
  7. 小明分享|ESP32-C3到底有哪些不一样的功能呢
  8. Chrome调试angularJS出现Uncaught SyntaxError: Unexpected identifier
  9. python脚本去除文件名里的空格
  10. 华为云大数据存储的冗余方式是三副本_揭秘!10+位DBA大神测评华为云DDS增强版实感...
  11. 计算机电脑用户名,如何改计算机用户名(administrator)
  12. CS:APP第六章知识总结(内存、缓存、locality)
  13. 解决VScode终端管理员运行问题
  14. 苹果 CEO 为什么选中了何同学?
  15. 华芯微特SWM181学习笔记--GPIO应用与环境搭建
  16. SceneTree类
  17. 新增商品(商品维护模块)
  18. CC3200之ADC引脚使用+ad转换器的基本原理
  19. sanity check
  20. 计算机毕业设计系列基于SSM的网上书城系统

热门文章

  1. CAD图纸反复修改?试试CAD替换工具!
  2. java爬取中国银行汇率数据
  3. JS与jQuery小结
  4. 【深度长文】细思极恐的YouTube可跳过广告
  5. 这一届科研计算人赶DDL红宝书:学生篇
  6. 烟气监测数据转IEC104规约对接电业局平台-国能赤峰生物发电项目
  7. GBDT(梯度提升决策树)算法(详细版)
  8. 这个错误该怎么解决啊?
  9. cak数控车床是计算机控制吗,CAK3675数控车床夹盘液压系统的设计(附CAD图纸).doc...
  10. 如何在JavaScript中创建RSS阅读器应用程序