diff --git a/components/drivers/rtc/SConscript b/components/drivers/rtc/SConscript index 9191ffec97db8d8d6d96a32913da8505c056ee57..e1f8f433c1671af179e9f131b737a87d12f57620 100644 --- a/components/drivers/rtc/SConscript +++ b/components/drivers/rtc/SConscript @@ -7,6 +7,8 @@ rtc = ['rtc.c'] rtc_alarm = ['alarm.c'] +soft_rtc = ['soft_rtc.c'] + CPPPATH = [cwd + '/../include'] group = [] @@ -14,6 +16,8 @@ if GetDepend(['RT_USING_RTC']): src = src + rtc if GetDepend(['RT_USING_ALARM']): src = src + rtc_alarm + if GetDepend(['RT_USING_SOFT_RTC']): + src = src + soft_rtc group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_RTC'], CPPPATH = CPPPATH) diff --git a/components/drivers/rtc/soft_rtc.c b/components/drivers/rtc/soft_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..6db2136ad4b11567f9da32b41da307b438abd116 --- /dev/null +++ b/components/drivers/rtc/soft_rtc.c @@ -0,0 +1,107 @@ +/* + * File : soft_rtc.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-01-30 armink the first version + */ + +#include +#include +#include + +#include + +#ifdef RT_USING_SOFT_RTC + +/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */ +#define RTC_TIME_INIT(year, month, day, hour, minute, second) \ + {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second} + +#ifndef SOFT_RTC_TIME_DEFAULT +#define SOFT_RTC_TIME_DEFAULT RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0) +#endif + +static struct rt_device soft_rtc_dev; +static rt_tick_t init_tick; +static time_t init_time; + +static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) +{ + time_t *time; + struct tm time_temp; + + RT_ASSERT(dev != RT_NULL); + memset(&time_temp, 0, sizeof(struct tm)); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + time = (time_t *) args; + *time = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND; + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + { + time = (time_t *) args; + init_time = *time - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND; + break; + } + } + + return RT_EOK; +} + +int rt_soft_rtc_init(void) +{ + static rt_bool_t init_ok = RT_FALSE; + struct tm time_new = SOFT_RTC_TIME_DEFAULT; + + if (init_ok) + { + return 0; + } + /* make sure only one 'rtc' device */ + RT_ASSERT(!rt_device_find("rtc")); + + init_tick = rt_tick_get(); + init_time = mktime(&time_new); + + soft_rtc_dev.type = RT_Device_Class_RTC; + + /* register rtc device */ + soft_rtc_dev.init = RT_NULL; + soft_rtc_dev.open = RT_NULL; + soft_rtc_dev.close = RT_NULL; + soft_rtc_dev.read = RT_NULL; + soft_rtc_dev.write = RT_NULL; + soft_rtc_dev.control = soft_rtc_control; + + /* no private */ + soft_rtc_dev.user_data = RT_NULL; + + rt_device_register(&soft_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR); + + init_ok = RT_TRUE; + + return 0; +} +INIT_DEVICE_EXPORT(rt_soft_rtc_init); + +#endif /* RT_USING_SOFT_RTC */