drv_rtc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. * Copyright (c) 2022, xiaoxiaolisunny
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2022-06-10 xiaoxiaolisunny first version
  10. */
  11. #include <board.h>
  12. #include <rtdbg.h>
  13. #include <rtthread.h>
  14. #include <rtdevice.h>
  15. #include <sys/time.h>
  16. #ifdef BSP_USING_RTC
  17. static rt_rtc_dev_t hc32_rtc_dev;
  18. static rt_err_t hc32_rtc_get_time_stamp(struct timeval *tv)
  19. {
  20. stc_rtc_time_t stcRtcTime = {0};
  21. stc_rtc_date_t stcRtcDate = {0};
  22. struct tm tm_new = {0};
  23. RTC_GetTime(RTC_DATA_FMT_DEC, &stcRtcTime);
  24. RTC_GetDate(RTC_DATA_FMT_DEC, &stcRtcDate);
  25. tm_new.tm_sec = stcRtcTime.u8Second;
  26. tm_new.tm_min = stcRtcTime.u8Minute;
  27. tm_new.tm_hour = stcRtcTime.u8Hour;
  28. if(stcRtcDate.u8Month == 0)
  29. {
  30. tm_new.tm_mday = stcRtcDate.u8Day + 1;
  31. tm_new.tm_mon = stcRtcDate.u8Month;
  32. }
  33. else
  34. {
  35. tm_new.tm_mday = stcRtcDate.u8Day ;
  36. tm_new.tm_mon = stcRtcDate.u8Month - 1;
  37. }
  38. tm_new.tm_year = stcRtcDate.u8Year + 100;
  39. tv->tv_sec = timegm(&tm_new);
  40. return RT_EOK;
  41. }
  42. static rt_err_t hc32_rtc_set_time_stamp(time_t time_stamp)
  43. {
  44. stc_rtc_time_t stcRtcTime = {0};
  45. stc_rtc_date_t stcRtcDate = {0};
  46. struct tm p_tm = {0};
  47. gmtime_r(&time_stamp, &p_tm);
  48. if (p_tm.tm_year < 100)
  49. {
  50. return -RT_ERROR;
  51. }
  52. stcRtcTime.u8Second = p_tm.tm_sec ;
  53. stcRtcTime.u8Minute = p_tm.tm_min ;
  54. stcRtcTime.u8Hour = p_tm.tm_hour;
  55. stcRtcDate.u8Day = p_tm.tm_mday;
  56. stcRtcDate.u8Month = p_tm.tm_mon + 1;
  57. stcRtcDate.u8Year = p_tm.tm_year - 100;
  58. stcRtcDate.u8Weekday = p_tm.tm_wday;
  59. if (LL_OK != RTC_SetTime(RTC_DATA_FMT_DEC, &stcRtcTime))
  60. {
  61. return -RT_ERROR;
  62. }
  63. if (LL_OK != RTC_SetDate(RTC_DATA_FMT_DEC, &stcRtcDate))
  64. {
  65. return -RT_ERROR;
  66. }
  67. LOG_D("set rtc time.");
  68. return RT_EOK;
  69. }
  70. static rt_err_t hc32_rtc_init(void)
  71. {
  72. stc_rtc_init_t stcRtcInit;
  73. #ifdef BSP_RTC_USING_XTAL32
  74. stc_clock_xtal32_init_t stcXtal32Init;
  75. /* Xtal32 config */
  76. stcXtal32Init.u8State = CLK_XTAL32_ON;
  77. stcXtal32Init.u8Drv = CLK_XTAL32_DRV_HIGH;
  78. stcXtal32Init.u8Filter = CLK_XTAL32_FILTER_RUN_MD;
  79. (void)CLK_Xtal32Init(&stcXtal32Init);
  80. /* Waiting for XTAL32 stabilization */
  81. rt_thread_delay(100);
  82. #endif
  83. /* RTC stopped */
  84. if (DISABLE == RTC_GetCounterState())
  85. {
  86. /* Reset RTC counter */
  87. if (LL_ERR_TIMEOUT == RTC_DeInit())
  88. {
  89. return -RT_ERROR;
  90. }
  91. else
  92. {
  93. /* Configure structure initialization */
  94. (void)RTC_StructInit(&stcRtcInit);
  95. /* Configuration RTC structure */
  96. #ifdef BSP_RTC_USING_XTAL32
  97. stcRtcInit.u8ClockSrc = RTC_CLK_SRC_XTAL32;
  98. #else
  99. stcRtcInit.u8ClockSrc = RTC_CLK_SRC_LRC;
  100. #endif
  101. stcRtcInit.u8HourFormat = RTC_HOUR_FMT_24H;
  102. (void)RTC_Init(&stcRtcInit);
  103. /* Startup RTC count */
  104. RTC_Cmd(ENABLE);
  105. }
  106. }
  107. return RT_EOK;
  108. }
  109. static rt_err_t hc32_rtc_get_secs(time_t *sec)
  110. {
  111. struct timeval tv;
  112. hc32_rtc_get_time_stamp(&tv);
  113. *(time_t *) sec = tv.tv_sec;
  114. LOG_D("RTC: get rtc_time %d", *sec);
  115. return RT_EOK;
  116. }
  117. static rt_err_t hc32_rtc_set_secs(time_t *sec)
  118. {
  119. rt_err_t result = RT_EOK;
  120. if (hc32_rtc_set_time_stamp(*sec))
  121. {
  122. result = -RT_ERROR;
  123. }
  124. LOG_D("RTC: set rtc_time %d", *sec);
  125. return result;
  126. }
  127. const static struct rt_rtc_ops hc32_rtc_ops =
  128. {
  129. hc32_rtc_init,
  130. hc32_rtc_get_secs,
  131. hc32_rtc_set_secs,
  132. RT_NULL,
  133. RT_NULL,
  134. hc32_rtc_get_time_stamp,
  135. RT_NULL
  136. };
  137. int rt_hw_rtc_init(void)
  138. {
  139. rt_err_t result;
  140. hc32_rtc_dev.ops = &hc32_rtc_ops;
  141. result = rt_hw_rtc_register(&hc32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
  142. if (result != RT_EOK)
  143. {
  144. LOG_E("rtc register err code: %d", result);
  145. return result;
  146. }
  147. LOG_D("rtc init success");
  148. return RT_EOK;
  149. }
  150. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  151. #endif /* BSP_USING_RTC */