stm32_rtc_v2.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (C) 2013 by Uwe Bonnes(bon@elektron.ikp,physik.tu-darmmstadt.de).
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*
  34. * \verbatim
  35. * $Id: stm32_rtc_v2.c 5409 2013-10-17 11:59:53Z u_bonnes $
  36. * \endverbatim
  37. */
  38. #include <cfg/os.h>
  39. #include <cfg/clock.h>
  40. #include <cfg/arch.h>
  41. #include <sys/event.h>
  42. #include <sys/timer.h>
  43. #include <dev/rtc.h>
  44. #include <cfg/arch/gpio.h>
  45. #include <arch/cm3/stm/stm32xxxx.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <time.h>
  49. /*!
  50. * \brief Get status of the STM32 V2 hardware clock.
  51. *
  52. * \param sflags Points to an unsigned long that receives the status flags.
  53. * - Bit 0: Backup Domain Reset happened.
  54. * - Bit 5: Alarm occured.
  55. * \return 0 on success or -1 in case of an error.
  56. */
  57. static int Stm32RtcGetStatus(NUTRTC *rtc, uint32_t *sflags)
  58. {
  59. uint32_t res = 0;
  60. /* Check for power failure */
  61. if (!(RTC->ISR & RTC_ISR_INITS)) {
  62. res = 1;
  63. }
  64. if (sflags) {
  65. *sflags = res;
  66. return 0;
  67. } else {
  68. return -1;
  69. }
  70. }
  71. /*!
  72. * \brief Get date and time from an STM32 V2 hardware clock.
  73. *
  74. * \param tm Points to a structure that receives the date and time
  75. * information.
  76. *
  77. * \return 0 on success or -1 in case of an error.
  78. */
  79. int Stm32RtcGetClock(NUTRTC *rtc, struct _tm *tm)
  80. {
  81. if (tm)
  82. {
  83. tm->tm_mday = ((RTC->DR >> 0) & 0xf) + (((RTC->DR >> 4) & 0x3) * 10);
  84. tm->tm_mon = ((RTC->DR >> 8) & 0xf) + (((RTC->DR >> 12) & 0x1) * 10);
  85. tm->tm_mon -= 1;
  86. tm->tm_year = ((RTC->DR >> 16) & 0xf) + (((RTC->DR >> 20) & 0xf) * 10)
  87. + 100;
  88. tm->tm_hour = ((RTC->TR >> 16) & 0xf) + (((RTC->TR >> 20) & 0x7) * 10);
  89. if (RTC->TR & RTC_TR_PM)
  90. tm->tm_hour += 12;
  91. tm->tm_min = ((RTC->TR >> 8) & 0xf) + (((RTC->TR >> 12) & 0x7) * 10);
  92. tm->tm_sec = ((RTC->TR >> 0) & 0xf) + (((RTC->TR >> 4) & 0x7) * 10);
  93. tm->tm_wday = ((RTC->DR >> 13) & 0x7);
  94. tm->tm_yday = 0/*FIXME*/;
  95. return 0;
  96. }
  97. else
  98. return -1;
  99. }
  100. /*!
  101. * \brief Set the STM32 V2 hardware clock.
  102. *
  103. * \param tm Points to a structure which contains the date and time
  104. * information.
  105. *
  106. * \return 0 on success or -1 in case of an error.
  107. */
  108. int Stm32RtcSetClock(NUTRTC *rtc, const struct _tm *tm)
  109. {
  110. uint32_t bcd_date, bcd_time, year, month;
  111. /* Allow RTC Write Access */
  112. RTC->WPR = 0xca;
  113. RTC->WPR = 0x53;
  114. /* Stop Clock*/
  115. RTC->ISR |= RTC_ISR_INIT;
  116. while (!(RTC->ISR & RTC_ISR_INITF));
  117. month = tm->tm_mon +1 ; /* Range 1..12*/
  118. year = tm->tm_year - 100; /* only two digits available*/
  119. bcd_date = (tm->tm_mday % 10);
  120. bcd_date |= (tm->tm_mday / 10) << 4;
  121. bcd_date |= ( month % 10) << 8;
  122. bcd_date |= ( month / 10) << 12;
  123. bcd_date |= (tm-> tm_wday ) << 13;
  124. bcd_date |= ( year % 10) << 16;
  125. bcd_date |= ( year / 10) << 20;
  126. RTC->DR = bcd_date;
  127. bcd_time = (tm->tm_sec % 10);
  128. bcd_time |= (tm->tm_sec / 10) << 4;
  129. bcd_time |= (tm->tm_min % 10) << 8;
  130. bcd_time |= (tm->tm_min / 10) << 12;
  131. bcd_time |= (tm->tm_hour % 10) << 16;
  132. bcd_time |= (tm->tm_hour / 10) << 20;
  133. RTC->TR = bcd_time;
  134. /*enable clock and inhibit RTC write access */
  135. RTC->ISR &= ~RTC_ISR_INIT;
  136. RTC->WPR = 0;
  137. return 0;
  138. }
  139. /*!
  140. * \brief Initialize the RTC in stm32f30x controller
  141. *
  142. * \return 0 on success or -1 in case of an error.
  143. *
  144. */
  145. int Stm32RtcInit(NUTRTC *rtc)
  146. {
  147. RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  148. PWR->CR |= PWR_CR_DBP;
  149. RCC->BDCR|= RCC_BDCR_RTCEN;
  150. if(RTC->ISR & RTC_ISR_INITS)
  151. /* The RTC has been set before. Do not set it*/
  152. /* Fixme: May give problems when reflashing to a different CLK source*/
  153. return 0;
  154. /* Backup Domain software reset*/
  155. RCC->BDCR |= RCC_BDCR_BDRST;
  156. RCC->BDCR &= ~RCC_BDCR_BDRST;
  157. /* Reenable RTC clk */
  158. RCC->BDCR|= RCC_BDCR_RTCEN;
  159. /* Select HSE/32 Clock for now. FIXME! */
  160. RCC->BDCR &= ~RCC_BDCR_RTCSEL;
  161. RCC->BDCR |= RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1;
  162. #if (HSE_VALUE % (32 * 250) != 0)
  163. #warning FIXME: RTC clock setup for given HSE_VALUE
  164. return -1;
  165. #endif
  166. /* Allow RTC Write Access */
  167. RTC->WPR = 0xca;
  168. RTC->WPR = 0x53;
  169. RTC->ISR |= RTC_ISR_INIT;
  170. while (!(RTC->ISR & RTC_ISR_INITF));
  171. /* 1 Mhz/32 = 31.250 kHz. So use 125 for the asyn prescaler */
  172. RTC->PRER = ((125 - 1) <<16) | ((HSE_VALUE/32/125) - 1);
  173. RTC->ISR &= ~RTC_ISR_INIT;
  174. RTC->WPR = 0; /* Disable RTC Write Access */
  175. return 0;
  176. }
  177. NUTRTC rtcStm32 = {
  178. /*.dcb = */ NULL, /*!< Driver control block */
  179. /*.rtc_init = */ Stm32RtcInit, /*!< Hardware initializatiuon, rtc_init */
  180. /*.rtc_gettime = */ Stm32RtcGetClock, /*!< Read date and time, rtc_gettime */
  181. /*.rtc_settime = */ Stm32RtcSetClock, /*!< Set date and time, rtc_settime */
  182. /*.rtc_getalarm = */ NULL, /*!< Read alarm date and time, rtc_getalarm */
  183. /*.rtc_setalarm = */ NULL, /*!< Set alarm date and time, rtc_setalarm */
  184. /*.rtc_getstatus = */ Stm32RtcGetStatus, /*!< Read status flags, rtc_getstatus */
  185. /*.rtc_clrstatus = */ NULL, /*!< Clear status flags, rtc_clrstatus */
  186. /*.alarm = */ NULL, /*!< Handle for alarm event queue, not supported right now */
  187. };