drv_rtc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. * 2022-05-09 xiaoxiaolisunny 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_date_time_t stcRtcDateTime = {0};
  20. struct tm tm_new = {0};
  21. RTC_GetDateTime(RtcDataFormatDec, &stcRtcDateTime);
  22. tm_new.tm_sec = stcRtcDateTime.u8Second;
  23. tm_new.tm_min = stcRtcDateTime.u8Minute;
  24. tm_new.tm_hour = stcRtcDateTime.u8Hour;
  25. tm_new.tm_mday = stcRtcDateTime.u8Day;
  26. tm_new.tm_mon = stcRtcDateTime.u8Month - 1;
  27. tm_new.tm_year = stcRtcDateTime.u8Year + 100;
  28. tm_new.tm_wday = stcRtcDateTime.u8Weekday;
  29. LOG_D("get rtc time.");
  30. return timegm(&tm_new);
  31. }
  32. static rt_err_t hc32_rtc_set_time_stamp(time_t time_stamp)
  33. {
  34. stc_rtc_date_time_t stcRtcDateTime = {0};
  35. struct tm *p_tm;
  36. p_tm = gmtime(&time_stamp);
  37. if (p_tm->tm_year < 100)
  38. {
  39. return -RT_ERROR;
  40. }
  41. stcRtcDateTime.u8Second = p_tm->tm_sec ;
  42. stcRtcDateTime.u8Minute = p_tm->tm_min ;
  43. stcRtcDateTime.u8Hour = p_tm->tm_hour;
  44. stcRtcDateTime.u8Day = p_tm->tm_mday;
  45. stcRtcDateTime.u8Month = p_tm->tm_mon + 1 ;
  46. stcRtcDateTime.u8Year = p_tm->tm_year - 100;
  47. stcRtcDateTime.u8Weekday = p_tm->tm_wday;
  48. if (Ok != RTC_SetDateTime(RtcDataFormatDec, &stcRtcDateTime, Enable, Enable))
  49. {
  50. return -RT_ERROR;
  51. }
  52. LOG_D("set rtc time.");
  53. return RT_EOK;
  54. }
  55. static rt_err_t hc32_rtc_init(struct rt_device *dev)
  56. {
  57. stc_rtc_init_t stcRtcInit;
  58. #ifdef BSP_RTC_USING_XTAL32
  59. stc_clk_xtal32_cfg_t stcXtal32Cfg;
  60. /* Xtal32 config */
  61. CLK_Xtal32Cmd(Disable);//stop xtal32
  62. stcXtal32Cfg.enDrv = ClkXtal32HighDrv;
  63. stcXtal32Cfg.enFilterMode = ClkXtal32FilterModeFull;
  64. CLK_Xtal32Config(&stcXtal32Cfg);
  65. CLK_Xtal32Cmd(Enable);//startup xtal32
  66. /* Waiting for XTAL32 stabilization */
  67. rt_thread_delay(1000);
  68. #endif
  69. /* Reset RTC counter */
  70. if (ErrorTimeout == RTC_DeInit())
  71. {
  72. return -RT_ERROR;
  73. }
  74. else
  75. {
  76. /* Configure structure initialization */
  77. stcRtcInit.enPeriodInt = RtcPeriodIntOneMin;
  78. //stcRtcInit.enTimeFormat = RtcTimeFormat24Hour;
  79. stcRtcInit.enCompenWay = RtcOutputCompenDistributed;
  80. stcRtcInit.enCompenEn = Disable;
  81. stcRtcInit.u16CompenVal = 0u;
  82. /* Configuration RTC structure */
  83. #ifdef BSP_RTC_USING_XTAL32
  84. stcRtcInit.enClkSource = RtcClkXtal32;
  85. #else
  86. stcRtcInit.enClkSource = RtcClkLrc;
  87. #endif
  88. stcRtcInit.enTimeFormat = RtcTimeFormat24Hour;
  89. (void)RTC_Init(&stcRtcInit);
  90. /* Startup RTC count */
  91. RTC_Cmd(Enable);
  92. }
  93. return RT_EOK;
  94. }
  95. static rt_err_t hc32_rtc_control(rt_device_t dev, int cmd, void *args)
  96. {
  97. rt_err_t result = RT_EOK;
  98. RT_ASSERT(dev != RT_NULL);
  99. switch (cmd)
  100. {
  101. case RT_DEVICE_CTRL_RTC_GET_TIME:
  102. *(rt_uint32_t *)args = hc32_rtc_get_time_stamp();
  103. LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
  104. break;
  105. case RT_DEVICE_CTRL_RTC_SET_TIME:
  106. if (hc32_rtc_set_time_stamp(*(rt_uint32_t *)args))
  107. {
  108. result = -RT_ERROR;
  109. }
  110. LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  111. break;
  112. default:
  113. return RT_EINVAL;
  114. }
  115. return result;
  116. }
  117. #ifdef RT_USING_DEVICE_OPS
  118. const static struct rt_device_ops rtc_ops =
  119. {
  120. RT_NULL,
  121. RT_NULL,
  122. RT_NULL,
  123. RT_NULL,
  124. RT_NULL,
  125. hc32_rtc_control
  126. };
  127. #endif
  128. static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag)
  129. {
  130. RT_ASSERT(device != RT_NULL);
  131. if (hc32_rtc_init(device) != RT_EOK)
  132. {
  133. return -RT_ERROR;
  134. }
  135. #ifdef RT_USING_DEVICE_OPS
  136. device->ops = &rtc_ops;
  137. #else
  138. device->init = RT_NULL;
  139. device->open = RT_NULL;
  140. device->close = RT_NULL;
  141. device->read = RT_NULL;
  142. device->write = RT_NULL;
  143. device->control = hc32_rtc_control;
  144. #endif
  145. device->type = RT_Device_Class_RTC;
  146. device->rx_indicate = RT_NULL;
  147. device->tx_complete = RT_NULL;
  148. device->user_data = RT_NULL;
  149. /* register a character device */
  150. return rt_device_register(device, name, flag);
  151. }
  152. int rt_hw_rtc_init(void)
  153. {
  154. rt_err_t result;
  155. result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
  156. if (result != RT_EOK)
  157. {
  158. LOG_E("rtc register err code: %d", result);
  159. return result;
  160. }
  161. LOG_D("rtc init success");
  162. return RT_EOK;
  163. }
  164. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  165. #endif /* BSP_USING_RTC */