drv_rtc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright (C) 2020, Huada Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-30 CDT first version
  9. */
  10. #include "board.h"
  11. #include <rtdbg.h>
  12. #ifdef BSP_USING_RTC
  13. static struct rt_device rtc;
  14. static time_t hc32_rtc_get_time_stamp(void)
  15. {
  16. stc_rtc_time_t stcRtcTime = {0};
  17. stc_rtc_date_t stcRtcDate = {0};
  18. struct tm tm_new = {0};
  19. RTC_GetTime(RTC_DATA_FORMAT_DEC, &stcRtcTime);
  20. RTC_GetDate(RTC_DATA_FORMAT_DEC, &stcRtcDate);
  21. tm_new.tm_sec = stcRtcTime.u8Second;
  22. tm_new.tm_min = stcRtcTime.u8Minute;
  23. tm_new.tm_hour = stcRtcTime.u8Hour;
  24. tm_new.tm_mday = stcRtcDate.u8Day;
  25. tm_new.tm_mon = stcRtcDate.u8Month - 1;
  26. tm_new.tm_year = stcRtcDate.u8Year + 100;
  27. tm_new.tm_wday = stcRtcDate.u8Weekday;
  28. LOG_D("get rtc time.");
  29. return mktime(&tm_new);
  30. }
  31. static rt_err_t hc32_rtc_set_time_stamp(time_t time_stamp)
  32. {
  33. stc_rtc_time_t stcRtcTime = {0};
  34. stc_rtc_date_t stcRtcDate = {0};
  35. struct tm *p_tm;
  36. p_tm = localtime(&time_stamp);
  37. if (p_tm->tm_year < 100)
  38. {
  39. return -RT_ERROR;
  40. }
  41. stcRtcTime.u8Second = p_tm->tm_sec ;
  42. stcRtcTime.u8Minute = p_tm->tm_min ;
  43. stcRtcTime.u8Hour = p_tm->tm_hour;
  44. stcRtcDate.u8Day = p_tm->tm_mday;
  45. stcRtcDate.u8Month = p_tm->tm_mon + 1 ;
  46. stcRtcDate.u8Year = p_tm->tm_year - 100;
  47. stcRtcDate.u8Weekday = p_tm->tm_wday;
  48. if (Ok != RTC_SetTime(RTC_DATA_FORMAT_DEC, &stcRtcTime))
  49. {
  50. return -RT_ERROR;
  51. }
  52. if (Ok != RTC_SetDate(RTC_DATA_FORMAT_DEC, &stcRtcDate))
  53. {
  54. return -RT_ERROR;
  55. }
  56. LOG_D("set rtc time.");
  57. return RT_EOK;
  58. }
  59. static rt_err_t hc32_rtc_init(struct rt_device *dev)
  60. {
  61. stc_rtc_init_t stcRtcInit;
  62. #ifdef BSP_RTC_USING_XTAL32
  63. stc_clk_xtal32_init_t stcXtal32Init;
  64. /* Xtal32 config */
  65. stcXtal32Init.u8Xtal32State = CLK_XTAL32_ON;
  66. stcXtal32Init.u8Xtal32Drv = CLK_XTAL32DRV_HIGH;
  67. stcXtal32Init.u8Xtal32NF = CLK_XTAL32NF_PART;
  68. (void)CLK_Xtal32Init(&stcXtal32Init);
  69. /* Waiting for XTAL32 stabilization */
  70. rt_thread_delay(1000);
  71. #endif
  72. /* Reset RTC counter */
  73. if (ErrorTimeout == RTC_DeInit())
  74. {
  75. return -RT_ERROR;
  76. }
  77. else
  78. {
  79. /* Configure structure initialization */
  80. (void)RTC_StructInit(&stcRtcInit);
  81. /* Configuration RTC structure */
  82. #ifdef BSP_RTC_USING_XTAL32
  83. stcRtcInit.u8ClockSource = RTC_CLOCK_SOURCE_XTAL32;
  84. #else
  85. stcRtcInit.u8ClockSource = RTC_CLOCK_SOURCE_RTCLRC;
  86. #endif
  87. stcRtcInit.u8HourFormat = RTC_HOUR_FORMAT_24;
  88. (void)RTC_Init(&stcRtcInit);
  89. /* Startup RTC count */
  90. RTC_Cmd(Enable);
  91. }
  92. return RT_EOK;
  93. }
  94. static rt_err_t hc32_rtc_control(rt_device_t dev, int cmd, void *args)
  95. {
  96. rt_err_t result = RT_EOK;
  97. RT_ASSERT(dev != RT_NULL);
  98. switch (cmd)
  99. {
  100. case RT_DEVICE_CTRL_RTC_GET_TIME:
  101. *(rt_uint32_t *)args = hc32_rtc_get_time_stamp();
  102. LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
  103. break;
  104. case RT_DEVICE_CTRL_RTC_SET_TIME:
  105. if (hc32_rtc_set_time_stamp(*(rt_uint32_t *)args))
  106. {
  107. result = -RT_ERROR;
  108. }
  109. LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  110. break;
  111. default:
  112. return RT_EINVAL;
  113. }
  114. return result;
  115. }
  116. #ifdef RT_USING_DEVICE_OPS
  117. const static struct rt_device_ops rtc_ops =
  118. {
  119. RT_NULL,
  120. RT_NULL,
  121. RT_NULL,
  122. RT_NULL,
  123. RT_NULL,
  124. hc32_rtc_control
  125. };
  126. #endif
  127. static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag)
  128. {
  129. RT_ASSERT(device != RT_NULL);
  130. if (hc32_rtc_init(device) != RT_EOK)
  131. {
  132. return -RT_ERROR;
  133. }
  134. #ifdef RT_USING_DEVICE_OPS
  135. device->ops = &rtc_ops;
  136. #else
  137. device->init = RT_NULL;
  138. device->open = RT_NULL;
  139. device->close = RT_NULL;
  140. device->read = RT_NULL;
  141. device->write = RT_NULL;
  142. device->control = hc32_rtc_control;
  143. #endif
  144. device->type = RT_Device_Class_RTC;
  145. device->rx_indicate = RT_NULL;
  146. device->tx_complete = RT_NULL;
  147. device->user_data = RT_NULL;
  148. /* register a character device */
  149. return rt_device_register(device, name, flag);
  150. }
  151. int rt_hw_rtc_init(void)
  152. {
  153. rt_err_t result;
  154. result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  155. if (result != RT_EOK)
  156. {
  157. LOG_E("rtc register err code: %d", result);
  158. return result;
  159. }
  160. LOG_D("rtc init success");
  161. return RT_EOK;
  162. }
  163. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  164. #endif /* BSP_USING_RTC */