diff --git a/bsp/hc32f460/Libraries/CMSIS/Device/HDSC/HC32F460/Include/ddl_config.h b/bsp/hc32f460/Libraries/CMSIS/Device/HDSC/HC32F460/Include/ddl_config.h index 7bddac1a11..adff07e808 100644 --- a/bsp/hc32f460/Libraries/CMSIS/Device/HDSC/HC32F460/Include/ddl_config.h +++ b/bsp/hc32f460/Libraries/CMSIS/Device/HDSC/HC32F460/Include/ddl_config.h @@ -86,7 +86,7 @@ extern "C" #define DDL_PWC_ENABLE (DDL_ON) #define DDL_QSPI_ENABLE (DDL_OFF) #define DDL_RMU_ENABLE (DDL_OFF) -#define DDL_RTC_ENABLE (DDL_OFF) +#define DDL_RTC_ENABLE (DDL_ON) #define DDL_SDIOC_ENABLE (DDL_OFF) #define DDL_SPI_ENABLE (DDL_OFF) #define DDL_SRAM_ENABLE (DDL_ON) diff --git a/bsp/hc32f460/Libraries/SConscript b/bsp/hc32f460/Libraries/SConscript index 579e740f6f..2172212e3e 100644 --- a/bsp/hc32f460/Libraries/SConscript +++ b/bsp/hc32f460/Libraries/SConscript @@ -19,6 +19,7 @@ HC32F460_StdPeriph_Driver/src/hc32f460_pwc.c HC32F460_StdPeriph_Driver/src/hc32f460_sram.c HC32F460_StdPeriph_Driver/src/hc32f460_utility.c HC32F460_StdPeriph_Driver/src/hc32f460_exint_nmi_swi.c +HC32F460_StdPeriph_Driver/src/hc32f460_rtc.c """) #src += Glob('HC32F460_StdPeriph_Driver/src/*.c') diff --git a/bsp/hc32f460/board/Kconfig b/bsp/hc32f460/board/Kconfig index dec846f03b..b91ebed820 100644 --- a/bsp/hc32f460/board/Kconfig +++ b/bsp/hc32f460/board/Kconfig @@ -35,6 +35,25 @@ menu "On-chip Peripheral Drivers" default y endif + menuconfig BSP_USING_RTC + bool "Enable RTC" + select RT_USING_RTC + select RT_USING_LIBC + default n + + if BSP_USING_RTC + choice + prompt "Select clock source" + default BSP_RTC_USING_LRC + + config BSP_RTC_USING_XTAL32 + bool "RTC USING XTAL32" + + config BSP_RTC_USING_LRC + bool "RTC USING LRC" + endchoice + endif + endmenu diff --git a/bsp/hc32f460/drivers/SConscript b/bsp/hc32f460/drivers/SConscript index 9325fb936f..9986b973a5 100644 --- a/bsp/hc32f460/drivers/SConscript +++ b/bsp/hc32f460/drivers/SConscript @@ -14,6 +14,9 @@ if GetDepend(['RT_USING_PIN']): if GetDepend(['RT_USING_SERIAL']): src += ['drv_usart.c'] +if GetDepend('BSP_USING_RTC'): + src += ['drv_rtc.c'] + CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/hc32f460/drivers/drv_rtc.c b/bsp/hc32f460/drivers/drv_rtc.c new file mode 100644 index 0000000000..d80d37a9c6 --- /dev/null +++ b/bsp/hc32f460/drivers/drv_rtc.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-05-09 xiaoxiaolisunny first version + */ + +#include +#include +#include +#include +#include + +#ifdef BSP_USING_RTC + +static struct rt_device rtc; + +static time_t hc32_rtc_get_time_stamp(void) +{ + stc_rtc_date_time_t stcRtcDateTime = {0}; + struct tm tm_new = {0}; + + RTC_GetDateTime(RtcDataFormatDec, &stcRtcDateTime); + + tm_new.tm_sec = stcRtcDateTime.u8Second; + tm_new.tm_min = stcRtcDateTime.u8Minute; + tm_new.tm_hour = stcRtcDateTime.u8Hour; + tm_new.tm_mday = stcRtcDateTime.u8Day; + tm_new.tm_mon = stcRtcDateTime.u8Month - 1; + tm_new.tm_year = stcRtcDateTime.u8Year + 100; + tm_new.tm_wday = stcRtcDateTime.u8Weekday; + + LOG_D("get rtc time."); + return timegm(&tm_new); +} + +static rt_err_t hc32_rtc_set_time_stamp(time_t time_stamp) +{ + stc_rtc_date_time_t stcRtcDateTime = {0}; + struct tm *p_tm; + + p_tm = gmtime(&time_stamp); + if (p_tm->tm_year < 100) + { + return -RT_ERROR; + } + + stcRtcDateTime.u8Second = p_tm->tm_sec ; + stcRtcDateTime.u8Minute = p_tm->tm_min ; + stcRtcDateTime.u8Hour = p_tm->tm_hour; + stcRtcDateTime.u8Day = p_tm->tm_mday; + stcRtcDateTime.u8Month = p_tm->tm_mon + 1 ; + stcRtcDateTime.u8Year = p_tm->tm_year - 100; + stcRtcDateTime.u8Weekday = p_tm->tm_wday; + + if (Ok != RTC_SetDateTime(RtcDataFormatDec, &stcRtcDateTime, Enable, Enable)) + { + return -RT_ERROR; + } + + LOG_D("set rtc time."); + return RT_EOK; +} + +static rt_err_t hc32_rtc_init(struct rt_device *dev) +{ + stc_rtc_init_t stcRtcInit; + +#ifdef BSP_RTC_USING_XTAL32 + stc_clk_xtal32_cfg_t stcXtal32Cfg; + /* Xtal32 config */ + CLK_Xtal32Cmd(Disable);//stop xtal32 + stcXtal32Cfg.enDrv = ClkXtal32HighDrv; + stcXtal32Cfg.enFilterMode = ClkXtal32FilterModeFull; + CLK_Xtal32Config(&stcXtal32Cfg); + CLK_Xtal32Cmd(Enable);//startup xtal32 + + /* Waiting for XTAL32 stabilization */ + rt_thread_delay(1000); +#endif + + /* Reset RTC counter */ + if (ErrorTimeout == RTC_DeInit()) + { + return -RT_ERROR; + } + else + { + /* Configure structure initialization */ + stcRtcInit.enPeriodInt = RtcPeriodIntOneMin; + //stcRtcInit.enTimeFormat = RtcTimeFormat24Hour; + stcRtcInit.enCompenWay = RtcOutputCompenDistributed; + stcRtcInit.enCompenEn = Disable; + stcRtcInit.u16CompenVal = 0u; + /* Configuration RTC structure */ +#ifdef BSP_RTC_USING_XTAL32 + stcRtcInit.enClkSource = RtcClkXtal32; +#else + stcRtcInit.enClkSource = RtcClkLrc; +#endif + stcRtcInit.enTimeFormat = RtcTimeFormat24Hour; + (void)RTC_Init(&stcRtcInit); + /* Startup RTC count */ + RTC_Cmd(Enable); + } + + return RT_EOK; +} + +static rt_err_t hc32_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 = hc32_rtc_get_time_stamp(); + LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + if (hc32_rtc_set_time_stamp(*(rt_uint32_t *)args)) + { + result = -RT_ERROR; + } + LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args); + break; + default: + return RT_EINVAL; + } + + return result; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rtc_ops = +{ + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + hc32_rtc_control +}; +#endif + +static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag) +{ + RT_ASSERT(device != RT_NULL); + + if (hc32_rtc_init(device) != RT_EOK) + { + return -RT_ERROR; + } +#ifdef RT_USING_DEVICE_OPS + device->ops = &rtc_ops; +#else + device->init = RT_NULL; + device->open = RT_NULL; + device->close = RT_NULL; + device->read = RT_NULL; + device->write = RT_NULL; + device->control = hc32_rtc_control; +#endif + device->type = RT_Device_Class_RTC; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + device->user_data = RT_NULL; + + /* register a character device */ + return rt_device_register(device, name, flag); +} + +int rt_hw_rtc_init(void) +{ + rt_err_t result; + + result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR); + if (result != RT_EOK) + { + LOG_E("rtc register err code: %d", result); + return result; + } + LOG_D("rtc init success"); + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_rtc_init); + +#endif /* BSP_USING_RTC */