From a2a7f3c2d926388c71d0be5fca0309bfef81e523 Mon Sep 17 00:00:00 2001 From: iysheng Date: Mon, 5 Jul 2021 11:34:11 +0800 Subject: [PATCH 1/5] [components][rtc] Add RTC framework V2.0 to simplify RTC registration process --- components/drivers/include/drivers/rtc.h | 3 + components/drivers/include/drivers/rtc_core.h | 43 +++++++ components/drivers/rtc/SConscript | 4 +- components/drivers/rtc/rtc.c | 1 + components/drivers/rtc/rtc_core.c | 117 ++++++++++++++++++ components/libc/compilers/common/time.c | 9 ++ include/rtdef.h | 6 - 7 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 components/drivers/include/drivers/rtc_core.h create mode 100644 components/drivers/rtc/rtc_core.c diff --git a/components/drivers/include/drivers/rtc.h b/components/drivers/include/drivers/rtc.h index 4845937113..3a318357da 100644 --- a/components/drivers/include/drivers/rtc.h +++ b/components/drivers/include/drivers/rtc.h @@ -11,6 +11,9 @@ #ifndef __RTC_H__ #define __RTC_H__ +#include +#include + rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day); rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second); diff --git a/components/drivers/include/drivers/rtc_core.h b/components/drivers/include/drivers/rtc_core.h new file mode 100644 index 0000000000..c093a1d749 --- /dev/null +++ b/components/drivers/include/drivers/rtc_core.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-11 iysheng first version. + */ + +#ifndef __RTC_CORE_H__ +#define __RTC_CORE_H__ + +#include + +#define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 /**< get second time */ +#define RT_DEVICE_CTRL_RTC_SET_TIME 0x11 /**< set second time */ +#define RT_DEVICE_CTRL_RTC_GET_TIME_US 0x12 /**< get microsecond time */ +#define RT_DEVICE_CTRL_RTC_SET_TIME_US 0x13 /**< set microsecond time */ +#define RT_DEVICE_CTRL_RTC_GET_ALARM 0x14 /**< get alarm */ +#define RT_DEVICE_CTRL_RTC_SET_ALARM 0x15 /**< set alarm */ + +struct rt_rtc_ops +{ + rt_err_t (*init)(void); + rt_err_t (*get_secs)(void *arg); + rt_err_t (*set_secs)(void *arg); + rt_err_t (*get_alarm)(void *arg); + rt_err_t (*set_alarm)(void *arg); +}; + +typedef struct rt_rtc_device +{ + struct rt_device parent; + const struct rt_rtc_ops *ops; +} rt_rtc_dev_t; + +rt_err_t rt_rtc_dev_register(rt_rtc_dev_t *rtc, + const char *name, + rt_uint32_t flag, + void *data); + +#endif /* __RTC_CORE_H__ */ diff --git a/components/drivers/rtc/SConscript b/components/drivers/rtc/SConscript index e1f8f433c1..b922db70c2 100644 --- a/components/drivers/rtc/SConscript +++ b/components/drivers/rtc/SConscript @@ -13,7 +13,7 @@ CPPPATH = [cwd + '/../include'] group = [] if GetDepend(['RT_USING_RTC']): - src = src + rtc + src = src + ['rtc.c', 'rtc_core.c'] if GetDepend(['RT_USING_ALARM']): src = src + rtc_alarm if GetDepend(['RT_USING_SOFT_RTC']): @@ -21,4 +21,4 @@ if GetDepend(['RT_USING_RTC']): group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_RTC'], CPPPATH = CPPPATH) -Return('group') \ No newline at end of file +Return('group') diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c index 98b60f9f95..2b9397da90 100644 --- a/components/drivers/rtc/rtc.c +++ b/components/drivers/rtc/rtc.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef RT_USING_RTC diff --git a/components/drivers/rtc/rtc_core.c b/components/drivers/rtc/rtc_core.c new file mode 100644 index 0000000000..ada0ed283b --- /dev/null +++ b/components/drivers/rtc/rtc_core.c @@ -0,0 +1,117 @@ +/* + * COPYRIGHT (C) 2011-2021, Real-Thread Information Technology Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-11 iysheng first version. + */ + +#include + +#define TRY_DO_RTC_FUNC(rt_rtc_dev, func_name, args) \ + rt_rtc_dev->ops->func_name ? rt_rtc_dev->ops->func_name(args) : -RT_EINVAL; + +/* + * This function initializes rtc_core + */ +static rt_err_t rt_rtc_core_init(struct rt_device *dev) +{ + rt_rtc_dev_t *rtc_core; + + RT_ASSERT(dev != RT_NULL); + rtc_core = (rt_rtc_dev_t *)dev; + if (rtc_core->ops->init) + { + return (rtc_core->ops->init()); + } + + return (-RT_ENOSYS); +} + +static rt_err_t rt_rtc_core_open(struct rt_device *dev, rt_uint16_t oflag) +{ + return (RT_EOK); +} + +static rt_err_t rt_rtc_core_close(struct rt_device *dev) +{ + /* Add close member function in rt_rtc_ops when need, + * then call that function here. + * */ + return (RT_EOK); +} + +static rt_err_t rt_rtc_core_control(struct rt_device *dev, + int cmd, + void *args) +{ + rt_rtc_dev_t *rtc_core; + rt_err_t ret = -RT_EINVAL; + + RT_ASSERT(dev != RT_NULL); + rtc_core = (rt_rtc_dev_t *)dev; + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + ret = TRY_DO_RTC_FUNC(rtc_core, get_secs, args); + break; + case RT_DEVICE_CTRL_RTC_SET_TIME: + ret = TRY_DO_RTC_FUNC(rtc_core, set_secs, args); + break; + case RT_DEVICE_CTRL_RTC_GET_ALARM: + ret = TRY_DO_RTC_FUNC(rtc_core, get_alarm, args); + break; + case RT_DEVICE_CTRL_RTC_SET_ALARM: + ret = TRY_DO_RTC_FUNC(rtc_core, set_alarm, args); + break; + default: + break; + } + + return ret; +} +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rtc_core_ops = +{ + rt_rtc_core_init, + rt_rtc_core_open, + rt_rtc_core_close, + RT_NULL, + RT_NULL, + rt_rtc_core_control, +}; +#endif + +rt_err_t rt_rtc_dev_register(rt_rtc_dev_t *rtc, + const char *name, + rt_uint32_t flag, + void *data) +{ + struct rt_device *device; + RT_ASSERT(rtc != RT_NULL); + + device = &(rtc->parent); + + device->type = RT_Device_Class_RTC; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + device->ops = &rtc_core_ops; +#else + device->init = rt_rtc_core_init; + device->open = rt_rtc_core_open; + device->close = rt_rtc_core_close; + device->read = RT_NULL; + device->write = RT_NULL; + device->control = rt_rtc_core_control; +#endif + device->user_data = data; + + /* register a character device */ + return rt_device_register(device, name, flag); +} + diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c index deda18a560..e13f81c2f7 100644 --- a/components/libc/compilers/common/time.c +++ b/components/libc/compilers/common/time.c @@ -473,12 +473,17 @@ static int clock_time_system_init() rt_device_t device; time = 0; + +#ifdef RT_USING_RTC device = rt_device_find("rtc"); if (device != RT_NULL) { /* get realtime seconds */ rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); } +#else + LOG_W("Cannot find a RTC device to provide time!"); +#endif /* get tick */ tick = rt_tick_get(); @@ -591,6 +596,7 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1; +#ifdef RT_USING_RTC /* update for RTC device */ device = rt_device_find("rtc"); if (device != RT_NULL) @@ -599,6 +605,9 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second); } else +#else + LOG_W("Cannot find a RTC device to save time!"); +#endif return -1; return 0; diff --git a/include/rtdef.h b/include/rtdef.h index 111ac4a12c..2b4750330f 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -962,12 +962,6 @@ enum rt_device_class_type #define RT_DEVICE_CTRL_BLK_AUTOREFRESH 0x13 /**< block device : enter/exit auto refresh mode */ #define RT_DEVICE_CTRL_NETIF_GETMAC 0x10 /**< get mac address */ #define RT_DEVICE_CTRL_MTD_FORMAT 0x10 /**< format a MTD device */ -#define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 /**< get second time */ -#define RT_DEVICE_CTRL_RTC_SET_TIME 0x11 /**< set second time */ -#define RT_DEVICE_CTRL_RTC_GET_TIME_US 0x12 /**< get microsecond time */ -#define RT_DEVICE_CTRL_RTC_SET_TIME_US 0x13 /**< set microsecond time */ -#define RT_DEVICE_CTRL_RTC_GET_ALARM 0x14 /**< get alarm */ -#define RT_DEVICE_CTRL_RTC_SET_ALARM 0x15 /**< set alarm */ typedef struct rt_device *rt_device_t; From c08cdf145a100d36a5c172aeea3c6009b58a3c7a Mon Sep 17 00:00:00 2001 From: iysheng Date: Mon, 5 Jul 2021 11:23:49 +0800 Subject: [PATCH 2/5] [bsp][efm32] Fix RTC driver compile error --- bsp/efm32/drv_rtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bsp/efm32/drv_rtc.c b/bsp/efm32/drv_rtc.c index 75713fe3b4..9972d3c631 100644 --- a/bsp/efm32/drv_rtc.c +++ b/bsp/efm32/drv_rtc.c @@ -24,6 +24,8 @@ ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ + +#include #include "board.h" #include "hdl_interrupt.h" #include "drv_rtc.h" From e62943abd27b4b7cadd149ed34ccb1bb332c790d Mon Sep 17 00:00:00 2001 From: iysheng Date: Mon, 5 Jul 2021 11:24:06 +0800 Subject: [PATCH 3/5] [libcpu][arm][s3c24x0] Fix RTC driver compile error --- libcpu/arm/s3c24x0/rtc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcpu/arm/s3c24x0/rtc.c b/libcpu/arm/s3c24x0/rtc.c index 0f9484405c..5d374dfadf 100644 --- a/libcpu/arm/s3c24x0/rtc.c +++ b/libcpu/arm/s3c24x0/rtc.c @@ -12,11 +12,12 @@ */ #include +#include #include #include // #define RTC_DEBUG - +#ifdef RT_USING_RTC #define RTC_ENABLE RTCCON |= 0x01; /*RTC read and write enable */ #define RTC_DISABLE RTCCON &= ~0x01; /* RTC read and write disable */ #define BCD2BIN(n) (((((n) >> 4) & 0x0F) * 10) + ((n) & 0x0F)) @@ -183,3 +184,4 @@ void list_date() } FINSH_FUNCTION_EXPORT(list_date, list date); #endif +#endif From 2bd7e04827d7d1ccaeaba6f4c4fbea1bff85af03 Mon Sep 17 00:00:00 2001 From: iysheng Date: Mon, 5 Jul 2021 14:00:37 +0800 Subject: [PATCH 4/5] [components][rtc] Add microsecond resolution support with RTC framework V2.0 --- components/drivers/include/drivers/rtc_core.h | 2 ++ components/drivers/rtc/rtc_core.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/components/drivers/include/drivers/rtc_core.h b/components/drivers/include/drivers/rtc_core.h index c093a1d749..f0c7b64e94 100644 --- a/components/drivers/include/drivers/rtc_core.h +++ b/components/drivers/include/drivers/rtc_core.h @@ -27,6 +27,8 @@ struct rt_rtc_ops rt_err_t (*set_secs)(void *arg); rt_err_t (*get_alarm)(void *arg); rt_err_t (*set_alarm)(void *arg); + rt_err_t (*get_usecs)(void *arg); + rt_err_t (*set_usecs)(void *arg); }; typedef struct rt_rtc_device diff --git a/components/drivers/rtc/rtc_core.c b/components/drivers/rtc/rtc_core.c index ada0ed283b..80bb61c8aa 100644 --- a/components/drivers/rtc/rtc_core.c +++ b/components/drivers/rtc/rtc_core.c @@ -61,6 +61,12 @@ static rt_err_t rt_rtc_core_control(struct rt_device *dev, case RT_DEVICE_CTRL_RTC_SET_TIME: ret = TRY_DO_RTC_FUNC(rtc_core, set_secs, args); break; + case RT_DEVICE_CTRL_RTC_GET_TIME_US: + ret = TRY_DO_RTC_FUNC(rtc_core, get_usecs, args); + break; + case RT_DEVICE_CTRL_RTC_SET_TIME_US: + ret = TRY_DO_RTC_FUNC(rtc_core, set_usecs, args); + break; case RT_DEVICE_CTRL_RTC_GET_ALARM: ret = TRY_DO_RTC_FUNC(rtc_core, get_alarm, args); break; From ecc0981d1027b2712f27b1c28d7657cb97b93ca2 Mon Sep 17 00:00:00 2001 From: iysheng Date: Mon, 5 Jul 2021 14:01:01 +0800 Subject: [PATCH 5/5] [bsp][stm32] Implement stm32 rtc driver to RTC framework V2.0 --- bsp/stm32/libraries/HAL_Drivers/drv_rtc.c | 142 ++++++++++------------ 1 file changed, 61 insertions(+), 81 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c b/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c index 88c96aa5b8..15968a178c 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c @@ -8,6 +8,7 @@ * 2018-12-04 balanceTWK first version * 2020-10-14 Dozingfiretruck Porting for stm32wbxx * 2021-02-05 Meco Man fix the problem of mixing local time and UTC time + * 2021-07-05 iysheng implement RTC framework V2.0 */ #include "board.h" @@ -25,8 +26,6 @@ #define BKUP_REG_DATA 0xA5A5 -static struct rt_device rtc; - static RTC_HandleTypeDef RTC_Handler; RT_WEAK uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister) @@ -102,34 +101,6 @@ static rt_err_t set_rtc_time_stamp(time_t time_stamp) return RT_EOK; } -static void rt_rtc_init(void) -{ -#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB) - __HAL_RCC_PWR_CLK_ENABLE(); -#endif - - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; -#ifdef BSP_RTC_USING_LSI -#ifdef SOC_SERIES_STM32WB -RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - RCC_OscInitStruct.LSEState = RCC_LSE_OFF; - RCC_OscInitStruct.LSIState = RCC_LSI_ON; -#else - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - RCC_OscInitStruct.LSEState = RCC_LSE_OFF; - RCC_OscInitStruct.LSIState = RCC_LSI_ON; -#endif -#else - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - RCC_OscInitStruct.LSEState = RCC_LSE_ON; - RCC_OscInitStruct.LSIState = RCC_LSI_OFF; -#endif - HAL_RCC_OscConfig(&RCC_OscInitStruct); -} - #ifdef SOC_SERIES_STM32F1 /* update RTC_BKP_DRx*/ static void rt_rtc_f1_bkp_update(void) @@ -160,7 +131,7 @@ static void rt_rtc_f1_bkp_update(void) } #endif -static rt_err_t rt_rtc_config(struct rt_device *dev) +static rt_err_t rt_rtc_config(void) { RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; @@ -234,81 +205,90 @@ static rt_err_t rt_rtc_config(struct rt_device *dev) return RT_EOK; } -static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args) +static rt_err_t stm32_rtc_init(void) +{ +#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB) + __HAL_RCC_PWR_CLK_ENABLE(); +#endif + + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; +#ifdef BSP_RTC_USING_LSI +#ifdef SOC_SERIES_STM32WB +RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; +#else + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; +#endif +#else + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_OFF; +#endif + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + if (rt_rtc_config() != RT_EOK) + { + LOG_E("rtc init failed."); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t stm32_rtc_get_secs(void *args) +{ + *(rt_uint32_t *)args = get_rtc_timestamp(); + LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args); + + return RT_EOK; +} + +static rt_err_t stm32_rtc_set_secs(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(); - LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args); - break; - case RT_DEVICE_CTRL_RTC_SET_TIME: - if (set_rtc_time_stamp(*(rt_uint32_t *)args)) - { - result = -RT_ERROR; - } - LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args); - break; + if (set_rtc_time_stamp(*(rt_uint32_t *)args)) + { + result = -RT_ERROR; } + LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args); return result; } -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rtc_ops = +static const struct rt_rtc_ops stm32_rtc_ops = { + stm32_rtc_init, + stm32_rtc_get_secs, /* get_secs */ + stm32_rtc_set_secs, /* set secs */ RT_NULL, RT_NULL, RT_NULL, RT_NULL, - RT_NULL, - rt_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); +static rt_rtc_dev_t stm32_rtc_dev; - rt_rtc_init(); - if (rt_rtc_config(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 = rt_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) +static int rt_hw_rtc_init(void) { rt_err_t result; - result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR); + + stm32_rtc_dev.ops = &stm32_rtc_ops; + result = rt_rtc_dev_register(&stm32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL); 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_ONCHIP_RTC */