diff --git a/components/drivers/rtc/SConscript b/components/drivers/rtc/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..b2d50de7588bea6163c3b528839c866bc3ed2b95 --- /dev/null +++ b/components/drivers/rtc/SConscript @@ -0,0 +1,8 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd + '/../include'] +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_RTC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..df5e635453a048bf23f4d6e105c4e3a3dee62c10 --- /dev/null +++ b/components/drivers/rtc/rtc.c @@ -0,0 +1,163 @@ +/* + * File : rtc.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-29 aozima first version. + * 2012-04-12 aozima optimization: find rtc device only first. + * 2012-04-16 aozima add scheduler lock for set_date and set_time. + */ + +#include +#include +#include + +/** \brief returns the current time. + * + * \param time_t * t the timestamp pointer, if not used, keep NULL. + * \return time_t return timestamp current. + * + */ +/* for IAR 6.2 later Compiler */ +#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 +#pragma module_name = "?time" +time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */ +#else +time_t time(time_t* t) +#endif +{ + static rt_device_t device = RT_NULL; + time_t time_now = 0; + + /* optimization: find rtc device only first. */ + if (device == RT_NULL) + { + device = rt_device_find("rtc"); + } + + /* read timestamp from RTC device. */ + if (device != RT_NULL) + { + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); + } + + /* if t is not NULL, write timestamp to *t */ + if (t != RT_NULL) + { + *t = time_now; + } + + return time_now; +} + +/** \brief set system date(time not modify). + * + * \param rt_uint32_t year e.g: 2012. + * \param rt_uint32_t month e.g: 12 (1~12). + * \param rt_uint32_t day e.g: e.g: 31. + * \return rt_err_t if set success, return RT_EOK. + * + */ +rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day) +{ + time_t now; + struct tm * p_tm; + struct tm tm_new; + rt_device_t device; + + /* get current time */ + now = time(RT_NULL); + + /* lock scheduler. */ + rt_enter_critical(); + /* converts calendar time time into local time. */ + p_tm = localtime(&now); + /* copy the statically located variable */ + memcpy(&tm_new, p_tm, sizeof(struct tm)); + /* unlock scheduler. */ + rt_exit_critical(); + + /* update date. */ + tm_new.tm_year = year - 1900; + tm_new.tm_mon = month - 1; /* tm_mon: 0~11 */ + tm_new.tm_mday = day; + + /* converts the local time in time to calendar time. */ + now = mktime(&tm_new); + + device = rt_device_find("rtc"); + if (device == RT_NULL) + { + return -RT_ERROR; + } + + /* update to RTC device. */ + return rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); +} + +/** \brief set system time(date not modify). + * + * \param rt_uint32_t hour e.g: 0~23. + * \param rt_uint32_t minute e.g: 0~59. + * \param rt_uint32_t second e.g: 0~59. + * \return rt_err_t if set success, return RT_EOK. + * + */ +rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second) +{ + time_t now; + struct tm * p_tm; + struct tm tm_new; + rt_device_t device; + + /* get current time */ + now = time(RT_NULL); + + /* lock scheduler. */ + rt_enter_critical(); + /* converts calendar time time into local time. */ + p_tm = localtime(&now); + /* copy the statically located variable */ + memcpy(&tm_new, p_tm, sizeof(struct tm)); + /* unlock scheduler. */ + rt_exit_critical(); + + /* update time. */ + tm_new.tm_hour = hour; + tm_new.tm_min = minute; + tm_new.tm_sec = second; + + /* converts the local time in time to calendar time. */ + now = mktime(&tm_new); + + device = rt_device_find("rtc"); + if (device == RT_NULL) + { + return RT_ERROR; + } + + /* update to RTC device. */ + return rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); +} + +#ifdef RT_USING_FINSH +#include + +void list_date(void) +{ + time_t now; + + now = time(RT_NULL); + rt_kprintf("%s\n", ctime(&now)); +} +FINSH_FUNCTION_EXPORT(list_date, show date and time.) + +FINSH_FUNCTION_EXPORT(set_date, set date. e.g: set_date(2010,2,28)) +FINSH_FUNCTION_EXPORT(set_time, set time. e.g: set_time(23,59,59)) +#endif