drv_rtc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-10-25 ZYH first implementation
  9. */
  10. #include "drv_rtc.h"
  11. #include <board.h>
  12. #include <rtdevice.h>
  13. #include <string.h>
  14. #include <time.h>
  15. RTC_HandleTypeDef hrtc;
  16. /* RTC init function */
  17. void MX_RTC_Init(void)
  18. {
  19. RTC_TimeTypeDef sTime;
  20. RTC_DateTypeDef sDate;
  21. /**Initialize RTC Only
  22. */
  23. hrtc.Instance = RTC;
  24. hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  25. hrtc.Init.AsynchPrediv = 127;
  26. hrtc.Init.SynchPrediv = 255;
  27. hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  28. hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  29. hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  30. RT_ASSERT(HAL_RTC_Init(&hrtc) == HAL_OK);
  31. /**Initialize RTC and set the Time and Date
  32. */
  33. if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2)
  34. {
  35. sTime.Hours = 22;
  36. sTime.Minutes = 28;
  37. sTime.Seconds = 0;
  38. sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  39. sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  40. RT_ASSERT(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK);
  41. sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
  42. sDate.Month = RTC_MONTH_OCTOBER;
  43. sDate.Date = 26;
  44. sDate.Year = 17;
  45. RT_ASSERT(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK);
  46. }
  47. HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, 0x32F2);
  48. }
  49. void HAL_RTC_MspInit(RTC_HandleTypeDef *rtcHandle)
  50. {
  51. if (rtcHandle->Instance == RTC)
  52. {
  53. /* USER CODE BEGIN RTC_MspInit 0 */
  54. /* USER CODE END RTC_MspInit 0 */
  55. /* RTC clock enable */
  56. __HAL_RCC_RTC_ENABLE();
  57. /* USER CODE BEGIN RTC_MspInit 1 */
  58. /* USER CODE END RTC_MspInit 1 */
  59. }
  60. }
  61. void HAL_RTC_MspDeInit(RTC_HandleTypeDef *rtcHandle)
  62. {
  63. if (rtcHandle->Instance == RTC)
  64. {
  65. /* USER CODE BEGIN RTC_MspDeInit 0 */
  66. /* USER CODE END RTC_MspDeInit 0 */
  67. /* Peripheral clock disable */
  68. __HAL_RCC_RTC_DISABLE();
  69. /* USER CODE BEGIN RTC_MspDeInit 1 */
  70. /* USER CODE END RTC_MspDeInit 1 */
  71. }
  72. }
  73. static rt_err_t stm32_rtc_control(struct rt_device *dev,
  74. int cmd,
  75. void *args)
  76. {
  77. struct tm *tm_now;
  78. struct tm now;
  79. RTC_TimeTypeDef sTime;
  80. RTC_DateTypeDef sDate;
  81. rt_enter_critical();
  82. /* converts calendar time time into local time. */
  83. tm_now = localtime((const time_t *) args);
  84. /* copy the statically located variable */
  85. memcpy(&now, tm_now, sizeof(struct tm));
  86. /* unlock scheduler. */
  87. rt_exit_critical();
  88. switch (cmd)
  89. {
  90. case RT_DEVICE_CTRL_RTC_GET_TIME:
  91. HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  92. HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
  93. now.tm_hour = sTime.Hours;
  94. now.tm_min = sTime.Minutes;
  95. now.tm_sec = sTime.Seconds;
  96. now.tm_year = sDate.Year + 100;
  97. now.tm_mon = sDate.Month - 1;
  98. now.tm_mday = sDate.Date;
  99. *((time_t *)args) = mktime(&now);
  100. break;
  101. case RT_DEVICE_CTRL_RTC_SET_TIME:
  102. sTime.Hours = now.tm_hour;
  103. sTime.Minutes = now.tm_min;
  104. sTime.Seconds = now.tm_sec;
  105. sDate.Year = now.tm_year - 100;
  106. sDate.Month = now.tm_mon + 1;
  107. sDate.Date = now.tm_mday;
  108. HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  109. HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
  110. break;
  111. }
  112. return RT_EOK;
  113. }
  114. static rt_err_t stm32_rtc_init(struct rt_device *dev)
  115. {
  116. return RT_EOK;
  117. }
  118. static rt_err_t stm32_rtc_open(struct rt_device *dev, rt_uint16_t oflag)
  119. {
  120. return RT_EOK;
  121. }
  122. static rt_err_t stm32_rtc_close(struct rt_device *dev)
  123. {
  124. return RT_EOK;
  125. }
  126. static rt_size_t stm32_rtc_read(struct rt_device *dev,
  127. rt_off_t pos,
  128. void *buffer,
  129. rt_size_t size)
  130. {
  131. stm32_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
  132. return size;
  133. }
  134. static rt_size_t stm32_rtc_write(struct rt_device *dev,
  135. rt_off_t pos,
  136. const void *buffer,
  137. rt_size_t size)
  138. {
  139. stm32_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
  140. return size;
  141. }
  142. struct rt_device rtc_device;
  143. int rt_hw_rtc_init(void)
  144. {
  145. MX_RTC_Init();
  146. rtc_device.type = RT_Device_Class_RTC;
  147. rtc_device.rx_indicate = RT_NULL;
  148. rtc_device.tx_complete = RT_NULL;
  149. rtc_device.init = stm32_rtc_init;
  150. rtc_device.open = stm32_rtc_open;
  151. rtc_device.close = stm32_rtc_close;
  152. rtc_device.read = stm32_rtc_read;
  153. rtc_device.write = stm32_rtc_write;
  154. rtc_device.control = stm32_rtc_control;
  155. rtc_device.user_data = RT_NULL;
  156. /* register a character device */
  157. return rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_DEACTIVATE);
  158. }
  159. INIT_BOARD_EXPORT(rt_hw_rtc_init);