drv_rtc.c 4.6 KB

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