drv_rtc.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-14 Mr.Tiger first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "board.h"
  13. #include <sys/time.h>
  14. #include "hal_data.h"
  15. #ifdef BSP_USING_ONCHIP_RTC
  16. #define DBG_TAG "drv.rtc"
  17. #ifdef DRV_DEBUG
  18. #define DBG_LVL DBG_LOG
  19. #else
  20. #define DBG_LVL DBG_INFO
  21. #endif /* DRV_DEBUG */
  22. #include <rtdbg.h>
  23. static rt_err_t ra_rtc_init(void)
  24. {
  25. rt_err_t result = RT_EOK;
  26. if (R_RTC_Open(&g_rtc_ctrl, &g_rtc_cfg) != RT_EOK)
  27. {
  28. LOG_E("rtc init failed.");
  29. result = -RT_ERROR;
  30. }
  31. return result;
  32. }
  33. static time_t get_rtc_timestamp(void)
  34. {
  35. struct tm tm_new = {0};
  36. rtc_time_t g_current_time = {0};
  37. R_RTC_CalendarTimeGet(&g_rtc_ctrl, &g_current_time);
  38. tm_new.tm_year = g_current_time.tm_year;
  39. tm_new.tm_mon = g_current_time.tm_mon;
  40. tm_new.tm_mday = g_current_time.tm_mday;
  41. tm_new.tm_hour = g_current_time.tm_hour;
  42. tm_new.tm_min = g_current_time.tm_min;
  43. tm_new.tm_sec = g_current_time.tm_sec;
  44. tm_new.tm_wday = g_current_time.tm_wday;
  45. tm_new.tm_yday = g_current_time.tm_yday;
  46. tm_new.tm_isdst = g_current_time.tm_isdst;
  47. return timegm(&tm_new);
  48. }
  49. static rt_err_t ra_get_secs(void *args)
  50. {
  51. *(rt_uint32_t *)args = get_rtc_timestamp();
  52. LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
  53. return RT_EOK;
  54. }
  55. static rt_err_t set_rtc_time_stamp(time_t time_stamp)
  56. {
  57. struct tm now;
  58. rtc_time_t g_current_time = {0};
  59. gmtime_r(&time_stamp, &now);
  60. if (now.tm_year < 100)
  61. {
  62. return -RT_ERROR;
  63. }
  64. g_current_time.tm_sec = now.tm_sec ;
  65. g_current_time.tm_min = now.tm_min ;
  66. g_current_time.tm_hour = now.tm_hour;
  67. g_current_time.tm_mday = now.tm_mday;
  68. g_current_time.tm_mon = now.tm_mon;
  69. g_current_time.tm_year = now.tm_year;
  70. g_current_time.tm_wday = now.tm_wday;
  71. g_current_time.tm_yday = now.tm_yday;
  72. if (R_RTC_CalendarTimeSet(&g_rtc_ctrl, &g_current_time) != FSP_SUCCESS)
  73. {
  74. LOG_E("set rtc time failed.");
  75. return -RT_ERROR;
  76. }
  77. return RT_EOK;
  78. }
  79. static rt_err_t ra_set_secs(void *args)
  80. {
  81. rt_err_t result = RT_EOK;
  82. if (set_rtc_time_stamp(*(rt_uint32_t *)args))
  83. {
  84. result = -RT_ERROR;
  85. }
  86. LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  87. return result;
  88. }
  89. #ifdef RT_USING_ALARM
  90. static rt_err_t ra_get_alarm(void *arg)
  91. {
  92. rt_err_t result = RT_EOK;
  93. struct rt_rtc_wkalarm *wkalarm = (struct rt_rtc_wkalarm *)arg;
  94. rtc_alarm_time_t alarm_time_get =
  95. {
  96. .sec_match = RT_FALSE,
  97. .min_match = RT_FALSE,
  98. .hour_match = RT_FALSE,
  99. .mday_match = RT_FALSE,
  100. .mon_match = RT_FALSE,
  101. .year_match = RT_FALSE,
  102. .dayofweek_match = RT_FALSE,
  103. };
  104. if (RT_EOK == R_RTC_CalendarAlarmGet(&g_rtc_ctrl, &alarm_time_get))
  105. {
  106. wkalarm->tm_hour = alarm_time_get.time.tm_hour;
  107. wkalarm->tm_min = alarm_time_get.time.tm_min;
  108. wkalarm->tm_sec = alarm_time_get.time.tm_sec;
  109. }
  110. else
  111. {
  112. LOG_E("Calendar alarm Get failed.");
  113. }
  114. return result;
  115. }
  116. static rt_err_t ra_set_alarm(void *arg)
  117. {
  118. rt_err_t result = RT_EOK;
  119. struct rt_rtc_wkalarm *wkalarm = (struct rt_rtc_wkalarm *)arg;
  120. rtc_alarm_time_t alarm_time_set =
  121. {
  122. .sec_match = RT_TRUE,
  123. .min_match = RT_TRUE,
  124. .hour_match = RT_TRUE,
  125. .mday_match = RT_FALSE,
  126. .mon_match = RT_FALSE,
  127. .year_match = RT_FALSE,
  128. .dayofweek_match = RT_FALSE,
  129. };
  130. alarm_time_set.time.tm_hour = wkalarm->tm_hour;
  131. alarm_time_set.time.tm_min = wkalarm->tm_min;
  132. alarm_time_set.time.tm_sec = wkalarm->tm_sec;
  133. if (1 == wkalarm->enable)
  134. {
  135. if (RT_EOK != R_RTC_CalendarAlarmSet(&g_rtc_ctrl, &alarm_time_set))
  136. {
  137. LOG_E("Calendar alarm Set failed.");
  138. result = -RT_ERROR;
  139. }
  140. }
  141. else
  142. {
  143. alarm_time_set.sec_match = RT_FALSE;
  144. alarm_time_set.min_match = RT_FALSE;
  145. alarm_time_set.hour_match = RT_FALSE;
  146. if (RT_EOK != R_RTC_CalendarAlarmSet(&g_rtc_ctrl, &alarm_time_set))
  147. {
  148. LOG_E("Calendar alarm Stop failed.");
  149. result = -RT_ERROR;
  150. }
  151. }
  152. return result;
  153. }
  154. #endif /* RT_USING_ALARM */
  155. void rtc_callback(rtc_callback_args_t *p_args)
  156. {
  157. #ifdef RT_USING_ALARM
  158. static rt_device_t ra_device;
  159. if (RTC_EVENT_ALARM_IRQ == p_args->event)
  160. {
  161. rt_alarm_update(ra_device, 1);
  162. }
  163. #endif
  164. }
  165. static const struct rt_rtc_ops ra_rtc_ops =
  166. {
  167. .init = ra_rtc_init,
  168. .get_secs = ra_get_secs,
  169. .set_secs = ra_set_secs,
  170. #ifdef RT_USING_ALARM
  171. .set_alarm = ra_set_alarm,
  172. .get_alarm = ra_get_alarm,
  173. #endif
  174. };
  175. static rt_rtc_dev_t ra_rtc_dev;
  176. static int rt_hw_rtc_init(void)
  177. {
  178. rt_err_t result;
  179. ra_rtc_dev.ops = &ra_rtc_ops;
  180. result = rt_hw_rtc_register(&ra_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
  181. if (result != RT_EOK)
  182. {
  183. LOG_E("rtc register err code: %d", result);
  184. return result;
  185. }
  186. LOG_D("rtc init success");
  187. return RT_EOK;
  188. }
  189. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  190. #endif