drv_rtc.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. * 2018-10-23 XXXXzzzz000 first implementation,referance:stm32f4xx-HAL/drv_rtc.c
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include <rtdevice.h>
  14. #include <board.h>
  15. #include <string.h>
  16. #include <time.h>
  17. RTC_HandleTypeDef hrtc;
  18. /* RTC init function */
  19. void MX_RTC_Init(void)
  20. {
  21. RTC_TimeTypeDef sTime;
  22. RTC_DateTypeDef sDate;
  23. /* Initialize RTC Only */
  24. hrtc.Instance = RTC;
  25. hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  26. hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
  27. RT_ASSERT(HAL_RTC_Init(&hrtc) == HAL_OK);
  28. /* Initialize RTC and set the Time and Date */
  29. if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0x32F1)
  30. {
  31. sTime.Hours = 0x0;
  32. sTime.Minutes = 0x0;
  33. sTime.Seconds = 0x0;
  34. RT_ASSERT(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK);
  35. sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  36. sDate.Month = RTC_MONTH_JANUARY;
  37. sDate.Date = 1;
  38. sDate.Year = 0;
  39. RT_ASSERT(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK);
  40. }
  41. HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x32F1);
  42. }
  43. void HAL_RTC_MspInit(RTC_HandleTypeDef *rtcHandle)
  44. {
  45. RCC_OscInitTypeDef RCC_OscInitStruct;
  46. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  47. if (rtcHandle->Instance == RTC)
  48. {
  49. __HAL_RCC_PWR_CLK_ENABLE();
  50. HAL_PWR_EnableBkUpAccess();
  51. __HAL_RCC_BKP_CLK_ENABLE();
  52. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  53. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  54. RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  55. HAL_RCC_OscConfig(&RCC_OscInitStruct);
  56. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  57. PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  58. HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  59. __HAL_RCC_RTC_ENABLE();
  60. }
  61. }
  62. void HAL_RTC_MspDeInit(RTC_HandleTypeDef *rtcHandle)
  63. {
  64. if (rtcHandle->Instance == RTC)
  65. {
  66. /* 禁用RTC时钟 */
  67. __HAL_RCC_RTC_DISABLE();
  68. /* 禁用PWR时钟和读取备份域 */
  69. HAL_PWR_DisableBkUpAccess();
  70. __HAL_RCC_PWR_CLK_DISABLE();
  71. /* 禁用备份时钟:备份寄存器 */
  72. __HAL_RCC_BKP_CLK_DISABLE();
  73. }
  74. }
  75. static rt_err_t stm32_rtc_control(struct rt_device *dev,
  76. int cmd,
  77. void *args)
  78. {
  79. struct tm *tm_now;
  80. struct tm now;
  81. RTC_TimeTypeDef sTime;
  82. RTC_DateTypeDef sDate;
  83. switch (cmd)
  84. {
  85. case RT_DEVICE_CTRL_RTC_GET_TIME:
  86. HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  87. HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
  88. now.tm_hour = sTime.Hours;
  89. now.tm_min = sTime.Minutes;
  90. now.tm_sec = sTime.Seconds;
  91. now.tm_year = sDate.Year + 100;
  92. now.tm_mon = sDate.Month - 1;
  93. now.tm_mday = sDate.Date;
  94. *((time_t *)args) = mktime(&now);
  95. break;
  96. case RT_DEVICE_CTRL_RTC_SET_TIME:
  97. rt_enter_critical();
  98. /* converts calendar time time into local time. */
  99. tm_now = localtime((const time_t *)args);
  100. /* copy the statically located variable */
  101. memcpy(&now, tm_now, sizeof(struct tm));
  102. /* unlock scheduler. */
  103. rt_exit_critical();
  104. sTime.Hours = now.tm_hour;
  105. sTime.Minutes = now.tm_min;
  106. sTime.Seconds = now.tm_sec;
  107. sDate.Year = now.tm_year - 100;
  108. sDate.Month = now.tm_mon + 1;
  109. sDate.Date = now.tm_mday;
  110. HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  111. HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
  112. break;
  113. }
  114. return RT_EOK;
  115. }
  116. static rt_err_t stm32_rtc_init(struct rt_device *dev)
  117. {
  118. return RT_EOK;
  119. }
  120. static rt_err_t stm32_rtc_open(struct rt_device *dev, rt_uint16_t oflag)
  121. {
  122. return RT_EOK;
  123. }
  124. static rt_err_t stm32_rtc_close(struct rt_device *dev)
  125. {
  126. return RT_EOK;
  127. }
  128. static rt_size_t stm32_rtc_read(struct rt_device *dev,
  129. rt_off_t pos,
  130. void *buffer,
  131. rt_size_t size)
  132. {
  133. stm32_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
  134. return size;
  135. }
  136. static rt_size_t stm32_rtc_write(struct rt_device *dev,
  137. rt_off_t pos,
  138. const void *buffer,
  139. rt_size_t size)
  140. {
  141. stm32_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
  142. return size;
  143. }
  144. struct rt_device rtc_device;
  145. int rt_hw_rtc_init(void)
  146. {
  147. MX_RTC_Init();
  148. rtc_device.type = RT_Device_Class_RTC;
  149. rtc_device.rx_indicate = RT_NULL;
  150. rtc_device.tx_complete = RT_NULL;
  151. rtc_device.init = stm32_rtc_init;
  152. rtc_device.open = stm32_rtc_open;
  153. rtc_device.close = stm32_rtc_close;
  154. rtc_device.read = stm32_rtc_read;
  155. rtc_device.write = stm32_rtc_write;
  156. rtc_device.control = stm32_rtc_control;
  157. rtc_device.user_data = RT_NULL;
  158. /* register a character device */
  159. return rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
  160. }
  161. INIT_BOARD_EXPORT(rt_hw_rtc_init);
  162. static void rtc_set(uint8_t argc, char **argv)
  163. {
  164. rt_device_t rtc = rt_device_find("rtc");
  165. RT_ASSERT(rtc != NULL);
  166. struct tm now = {
  167. .tm_hour = 10,
  168. .tm_min = 35,
  169. .tm_sec = 0,
  170. .tm_year = 2018 - 1900,
  171. .tm_mon = 10 - 1,
  172. .tm_mday = 23,
  173. };
  174. time_t tim = mktime(&now);
  175. rt_device_control(rtc, RT_DEVICE_CTRL_RTC_SET_TIME, &tim);
  176. int ret = rt_device_write(rtc, 0, &tim, 0);
  177. }
  178. MSH_CMD_EXPORT(rtc_set, rtc_set yyyy mm dd hh mm ss);
  179. static void rtc_get(uint8_t argc, char **argv)
  180. {
  181. rt_device_t rtc = rt_device_find("rtc");
  182. RT_ASSERT(rtc != NULL);
  183. struct tm *tm_now;
  184. time_t tim;
  185. struct tm now;
  186. rt_device_control(rtc, RT_DEVICE_CTRL_RTC_GET_TIME, &tim);
  187. rt_enter_critical();
  188. tm_now = localtime(&tim);
  189. memcpy(&now, tm_now, sizeof(struct tm));
  190. rt_exit_critical();
  191. rt_kprintf("%d/%d/%d %d:%d:%d\n", now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
  192. }
  193. MSH_CMD_EXPORT(rtc_get, rtc_get);