drv_rtc.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*****************************************************************************
  2. * Copyright (c) 2019, Nations Technologies Inc.
  3. *
  4. * All rights reserved.
  5. * ****************************************************************************
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * - Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the disclaimer below.
  12. *
  13. * Nations' name may not be used to endorse or promote products derived from
  14. * this software without specific prior written permission.
  15. *
  16. * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  19. * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  22. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  25. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. * ****************************************************************************/
  27. /**
  28. * @file drv_rtc.c
  29. * @author Nations
  30. * @version v1.0.0
  31. *
  32. * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
  33. */
  34. #include "board.h"
  35. #include <sys/time.h>
  36. #include <rtdevice.h>
  37. #ifdef BSP_USING_RTC
  38. uint32_t SynchPrediv, AsynchPrediv;
  39. static rt_err_t n32_rtc_get_timeval(struct timeval *tv)
  40. {
  41. struct tm tm_new = {0};
  42. RTC_DateType RTC_DateStructure;
  43. RTC_TimeType RTC_TimeStructure;
  44. RTC_GetTime(RTC_FORMAT_BIN, &RTC_TimeStructure);
  45. RTC_GetDate(RTC_FORMAT_BIN, &RTC_DateStructure);
  46. tm_new.tm_sec = RTC_TimeStructure.Seconds;
  47. tm_new.tm_min = RTC_TimeStructure.Minutes;
  48. tm_new.tm_hour = RTC_TimeStructure.Hours;
  49. tm_new.tm_wday = RTC_DateStructure.WeekDay;
  50. tm_new.tm_mday = RTC_DateStructure.Date;
  51. tm_new.tm_mon = RTC_DateStructure.Month - 1;
  52. tm_new.tm_year = RTC_DateStructure.Year + 100;
  53. tv->tv_sec = timegm(&tm_new);
  54. return RT_EOK;
  55. }
  56. static rt_err_t set_rtc_time_stamp(time_t time_stamp)
  57. {
  58. struct tm time = {0};
  59. RTC_DateType RTC_DateStructure={0};
  60. RTC_TimeType RTC_TimeStructure={0};
  61. gmtime_r(&time_stamp, &time);
  62. if(time.tm_year < 100)
  63. {
  64. return -RT_ERROR;
  65. }
  66. RTC_TimeStructure.Seconds = time.tm_sec ;
  67. RTC_TimeStructure.Minutes = time.tm_min ;
  68. RTC_TimeStructure.Hours = time.tm_hour;
  69. RTC_DateStructure.Date = time.tm_mday;
  70. RTC_DateStructure.Month = time.tm_mon + 1 ;
  71. RTC_DateStructure.Year = time.tm_year - 100;
  72. RTC_DateStructure.WeekDay = time.tm_wday + 1;
  73. if(RTC_SetDate(RTC_FORMAT_BIN, &RTC_DateStructure) != SUCCESS)
  74. {
  75. return -RT_ERROR;
  76. }
  77. if(RTC_ConfigTime(RTC_FORMAT_BIN, &RTC_TimeStructure) != SUCCESS)
  78. {
  79. return -RT_ERROR;
  80. }
  81. rt_kprintf("set rtc time.\n");
  82. return RT_EOK;
  83. }
  84. static rt_err_t rt_rtc_config(void)
  85. {
  86. RTC_InitType RTC_InitStructure;
  87. /* Configure the RTC data register and RTC prescaler */
  88. RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
  89. RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
  90. RTC_InitStructure.RTC_HourFormat = RTC_24HOUR_FORMAT;
  91. /* Check on RTC init */
  92. if(RTC_Init(&RTC_InitStructure) != SUCCESS)
  93. {
  94. return -RT_ERROR;
  95. }
  96. return RT_EOK;
  97. }
  98. static rt_err_t n32_rtc_init(void)
  99. {
  100. /* Enable the PWR clock */
  101. RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR | RCC_APB1_PERIPH_BKP, ENABLE);
  102. RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
  103. /* Allow access to RTC */
  104. PWR_BackupAccessEnable(ENABLE);
  105. /* Reset Backup */
  106. BKP_DeInit();
  107. /* Disable RTC clock */
  108. RCC_EnableRtcClk(DISABLE);
  109. #ifdef BSP_RTC_USING_LSI
  110. rt_kprintf("rtc clock source is set lsi!\n");
  111. /* Enable the LSI OSC */
  112. RCC_EnableLsi(ENABLE);
  113. while(RCC_GetFlagStatus(RCC_FLAG_LSIRD) == RESET)
  114. {
  115. }
  116. RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSI);
  117. SynchPrediv = 0x136; // 39.64928KHz
  118. AsynchPrediv = 0x7F; // value range: 0-7F
  119. #else
  120. rt_kprintf("rtc clock source is set lse!\n");
  121. /* Enable the LSE OSC32_IN PC14 */
  122. RCC_EnableLsi(DISABLE); // LSI is turned off here to ensure that only one clock is turned on
  123. RCC_ConfigLse(RCC_LSE_ENABLE);
  124. while(RCC_GetFlagStatus(RCC_FLAG_LSERD) == RESET)
  125. {
  126. }
  127. RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSE);
  128. SynchPrediv = 0xFF; // 32.768KHz
  129. AsynchPrediv = 0x7F; // value range: 0-7F
  130. #endif /* BSP_RTC_USING_LSI */
  131. /* Enable the RTC Clock */
  132. RCC_EnableRtcClk(ENABLE);
  133. RTC_WaitForSynchro();
  134. if(rt_rtc_config() != RT_EOK)
  135. {
  136. rt_kprintf("rtc init failed.\n");
  137. return -RT_ERROR;
  138. }
  139. return RT_EOK;
  140. }
  141. static rt_err_t n32_rtc_get_secs(time_t *sec)
  142. {
  143. struct timeval tv;
  144. n32_rtc_get_timeval(&tv);
  145. *(time_t *) sec = tv.tv_sec;
  146. rt_kprintf("RTC: get rtc_time %d.\n", *sec);
  147. return RT_EOK;
  148. }
  149. static rt_err_t n32_rtc_set_secs(time_t *sec)
  150. {
  151. rt_err_t result = RT_EOK;
  152. if(set_rtc_time_stamp(*sec))
  153. {
  154. result = -RT_ERROR;
  155. }
  156. rt_kprintf("RTC: set rtc_time %d.\n", *sec);
  157. return result;
  158. }
  159. static const struct rt_rtc_ops n32_rtc_ops =
  160. {
  161. n32_rtc_init,
  162. n32_rtc_get_secs,
  163. n32_rtc_set_secs,
  164. RT_NULL,
  165. RT_NULL,
  166. n32_rtc_get_timeval,
  167. RT_NULL,
  168. };
  169. static rt_rtc_dev_t n32_rtc_dev;
  170. static int rt_hw_rtc_init(void)
  171. {
  172. rt_err_t result;
  173. n32_rtc_dev.ops = &n32_rtc_ops;
  174. result = rt_hw_rtc_register(&n32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
  175. if(result != RT_EOK)
  176. {
  177. rt_kprintf("rtc register error code: %d.\n", result);
  178. return result;
  179. }
  180. else
  181. {
  182. rt_kprintf("rtc initialize success.\n");
  183. }
  184. return RT_EOK;
  185. }
  186. INIT_DEVICE_EXPORT(rt_hw_rtc_init);
  187. #endif /* BSP_USING_RTC */