drv_rtc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. * 2022-05-16 shelton first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <sys/time.h>
  13. #include "drv_common.h"
  14. #ifdef BSP_USING_RTC
  15. //#define DRV_DEBUG
  16. #define LOG_TAG "drv.rtc"
  17. #include <drv_log.h>
  18. #define BKUP_REG_DATA 0xA5A5
  19. static time_t get_rtc_timestamp(void)
  20. {
  21. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  22. defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
  23. defined (SOC_SERIES_AT32F425)
  24. struct tm tm_new;
  25. ertc_time_type ertc_time_struct;
  26. ertc_calendar_get(&ertc_time_struct);
  27. tm_new.tm_sec = ertc_time_struct.sec;
  28. tm_new.tm_min = ertc_time_struct.min;
  29. tm_new.tm_hour = ertc_time_struct.hour;
  30. tm_new.tm_mday = ertc_time_struct.day;
  31. tm_new.tm_mon = ertc_time_struct.month - 1;
  32. tm_new.tm_year = ertc_time_struct.year + 100;
  33. LOG_D("get rtc time.");
  34. return timegm(&tm_new);
  35. #else
  36. return rtc_counter_get();
  37. #endif
  38. }
  39. static rt_err_t set_rtc_time_stamp(time_t time_stamp)
  40. {
  41. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  42. defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
  43. defined (SOC_SERIES_AT32F425)
  44. struct tm now;
  45. gmtime_r(&time_stamp, &now);
  46. if (now.tm_year < 100)
  47. {
  48. return -RT_ERROR;
  49. }
  50. /* set time */
  51. if(ertc_time_set(now.tm_hour, now.tm_min, now.tm_sec, ERTC_AM) != SUCCESS)
  52. {
  53. return -RT_ERROR;
  54. }
  55. /* set date */
  56. if(ertc_date_set(now.tm_year - 100, now.tm_mon + 1, now.tm_mday, now.tm_wday + 1) != SUCCESS)
  57. {
  58. return -RT_ERROR;
  59. }
  60. LOG_D("set rtc time.");
  61. /* indicator for the ertc configuration */
  62. ertc_bpr_data_write(ERTC_DT1, BKUP_REG_DATA);
  63. #else
  64. /* set the rtc counter value */
  65. rtc_counter_set(time_stamp);
  66. /* wait until last write operation on rtc registers has finished */
  67. rtc_wait_config_finish();
  68. LOG_D("set rtc time.");
  69. bpr_data_write(BPR_DATA1, BKUP_REG_DATA);
  70. #endif
  71. return RT_EOK;
  72. }
  73. static rt_err_t rt_rtc_config(void)
  74. {
  75. /* allow access to pattery powered domain */
  76. pwc_battery_powered_domain_access(TRUE);
  77. #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
  78. defined (SOC_SERIES_AT32F415) || defined (SOC_SERIES_AT32F421) || \
  79. defined (SOC_SERIES_AT32F425)
  80. /* select rtc clock source */
  81. #ifdef BSP_RTC_USING_LICK
  82. crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);
  83. #else
  84. crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);
  85. #endif /* BSP_RTC_USING_LICK */
  86. /* enable rtc */
  87. crm_ertc_clock_enable(TRUE);
  88. /* wait for ertc registers update */
  89. ertc_wait_update();
  90. if (ertc_bpr_data_read(ERTC_DT1)!= BKUP_REG_DATA)
  91. {
  92. LOG_I("RTC hasn't been configured, please use <date> command to config.");
  93. /* configure the ertc divider */
  94. ertc_divider_set(0x7F, 0xFF);
  95. /* configure the ertc hour mode */
  96. ertc_hour_mode_set(ERTC_HOUR_MODE_24);
  97. }
  98. #else
  99. #ifdef BSP_RTC_USING_LICK
  100. crm_rtc_clock_select(CRM_RTC_CLOCK_LICK);
  101. #else
  102. crm_rtc_clock_select(CRM_RTC_CLOCK_LEXT);
  103. #endif /* BSP_RTC_USING_LICK */
  104. /* enable rtc */
  105. crm_rtc_clock_enable(TRUE);
  106. /* wait for rtc registers update finish */
  107. rtc_wait_update_finish();
  108. /* wait until last write operation on rtc registers has finished */
  109. rtc_wait_config_finish();
  110. if (bpr_data_read(BPR_DATA1) != BKUP_REG_DATA)
  111. {
  112. LOG_I("RTC hasn't been configured, please use <date> command to config.");
  113. /* set rtc divider: set rtc period to 1sec */
  114. rtc_divider_set(32767);
  115. /* wait until last write operation on rtc registers has finished */
  116. rtc_wait_config_finish();
  117. }
  118. #endif
  119. return RT_EOK;
  120. }
  121. static rt_err_t _rtc_init(void)
  122. {
  123. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  124. #if defined (SOC_SERIES_AT32F403A) || defined (SOC_SERIES_AT32F407) || \
  125. defined (SOC_SERIES_AT32F413)
  126. crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
  127. #endif
  128. #ifdef BSP_RTC_USING_LICK
  129. crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  130. while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET);
  131. #else
  132. pwc_battery_powered_domain_access(TRUE);
  133. crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
  134. while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET);
  135. #endif /* BSP_RTC_USING_LICK */
  136. if (rt_rtc_config() != RT_EOK)
  137. {
  138. LOG_E("rtc init failed.");
  139. return -RT_ERROR;
  140. }
  141. return RT_EOK;
  142. }
  143. static rt_err_t _rtc_get_secs(time_t *args)
  144. {
  145. *(rt_uint32_t *)args = get_rtc_timestamp();
  146. LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
  147. return RT_EOK;
  148. }
  149. static rt_err_t _rtc_set_secs(time_t *args)
  150. {
  151. rt_err_t result = RT_EOK;
  152. if (set_rtc_time_stamp(*(rt_uint32_t *)args))
  153. {
  154. result = -RT_ERROR;
  155. }
  156. LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  157. return result;
  158. }
  159. static const struct rt_rtc_ops _rtc_ops =
  160. {
  161. _rtc_init,
  162. _rtc_get_secs,
  163. _rtc_set_secs,
  164. RT_NULL,
  165. RT_NULL,
  166. RT_NULL,
  167. RT_NULL,
  168. };
  169. static rt_rtc_dev_t at32_rtc_dev;
  170. int rt_hw_rtc_init(void)
  171. {
  172. rt_err_t result;
  173. at32_rtc_dev.ops = &_rtc_ops;
  174. result = rt_hw_rtc_register(&at32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR,RT_NULL);
  175. if (result != RT_EOK)
  176. {
  177. LOG_E("rtc register err code: %d", result);
  178. return result;
  179. }
  180. LOG_D("rtc init success");
  181. return RT_EOK;
  182. }
  183. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  184. #endif /* BSP_USING_RTC */