From a62a07446c20f010cf3838712226360ff0b9d042 Mon Sep 17 00:00:00 2001 From: armink Date: Tue, 13 Apr 2021 20:11:56 +0800 Subject: [PATCH] [bsp/simulator] Add windows rtc driver. --- bsp/simulator/drivers/drv_rtc.c | 144 ++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 bsp/simulator/drivers/drv_rtc.c diff --git a/bsp/simulator/drivers/drv_rtc.c b/bsp/simulator/drivers/drv_rtc.c new file mode 100644 index 0000000000..27a0861d52 --- /dev/null +++ b/bsp/simulator/drivers/drv_rtc.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-04-13 armink the first version + */ + +#include +#include +#include +#include + +#ifdef RT_USING_RTC + +static struct rt_device rtc_dev; + +#ifdef RT_USING_ALARM + +static struct rt_rtc_wkalarm wkalarm; +static struct rt_timer alarm_time; + +static void alarm_timeout(void *param) +{ + rt_alarm_update(param, 1); +} + +static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm) +{ + rt_tick_t next_tick; + + if (palarm->enable) + { + next_tick = RT_TICK_PER_SECOND; + rt_timer_control(&alarm_time, RT_TIMER_CTRL_SET_TIME, &next_tick); + rt_timer_start(&alarm_time); + } + else + { + rt_timer_stop(&alarm_time); + } +} + +#endif + +static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) +{ + __time32_t *t; + struct tm *newtime; + + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + { + t = (__time32_t *)args; + _time32(t); + /* TODO The libc time module not support timezone now. So get the time from locatime. */ + newtime = _localtime32(t); + *t = _mkgmtime32(newtime); + break; + } + case RT_DEVICE_CTRL_RTC_SET_TIME: + { +#ifdef RT_USING_ALARM + soft_rtc_alarm_update(&wkalarm); +#endif + break; + } +#ifdef RT_USING_ALARM + case RT_DEVICE_CTRL_RTC_GET_ALARM: + *((struct rt_rtc_wkalarm *)args) = wkalarm; + break; + case RT_DEVICE_CTRL_RTC_SET_ALARM: + wkalarm = *((struct rt_rtc_wkalarm *)args); + soft_rtc_alarm_update(&wkalarm); + break; +#endif + } + + return RT_EOK; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops soft_rtc_ops = +{ + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + soft_rtc_control +}; +#endif + +int rt_win_rtc_init(void) +{ + static rt_bool_t init_ok = RT_FALSE; + + if (init_ok) + { + return 0; + } + /* make sure only one 'rtc' device */ + RT_ASSERT(!rt_device_find("rtc")); + +#ifdef RT_USING_ALARM + rt_timer_init(&alarm_time, + "alarm", + alarm_timeout, + &rtc_dev, + 0, + RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); +#endif + + rtc_dev.type = RT_Device_Class_RTC; + + /* register rtc device */ +#ifdef RT_USING_DEVICE_OPS + rtc_dev.ops = &soft_rtc_ops; +#else + rtc_dev.init = RT_NULL; + rtc_dev.open = RT_NULL; + rtc_dev.close = RT_NULL; + rtc_dev.read = RT_NULL; + rtc_dev.write = RT_NULL; + rtc_dev.control = soft_rtc_control; +#endif + + /* no private */ + rtc_dev.user_data = RT_NULL; + + rt_device_register(&rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR); + + init_ok = RT_TRUE; + + return 0; +} +INIT_BOARD_EXPORT(rt_win_rtc_init); + +#endif /* RT_USING_RTC */