gd32_rtc.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "bsp/bsp_driver.h"
  4. #define IS_LEAP_YEAR(year) ((year % 4 == 0) && ( year % 100 != 0) || (year % 400 == 0))
  5. //static uint32_t time_ticks = 0;
  6. uint32_t time_ticks = 0;
  7. uint32_t rtc_second = 0;
  8. #define POWER_FIRSTFLAG_REG BKP_DATA_0
  9. #define POWER_FIRSTFLAG_VALUE 0x5AA5
  10. unsigned char check_rtc_time(void)
  11. {
  12. int rtcTime = rtc_counter_get();
  13. if(rtcTime > YEAR_20171201_UTS && rtcTime < YEAR_20571201_UTS)
  14. return 1;
  15. else
  16. return 0;
  17. }
  18. unsigned char check_utc_stamp_valid(uint32_t utc)
  19. {
  20. if(utc > YEAR_20171201_UTS && utc < YEAR_20571201_UTS)
  21. return 1;
  22. else
  23. return 0;
  24. }
  25. /* get utc timestamp --> second */
  26. uint32_t rtc_get_timestamp(void){
  27. return rtc_counter_get();
  28. }
  29. /* get utc timestamp --> macro second */
  30. uint64_t rtc_get_timestamp_ms(void){
  31. return (uint64_t)rtc_counter_get() * 1000 ;
  32. }
  33. void rtc_set_time_with_utc_second(uint32_t utc_s){
  34. /* wait until last write operation on RTC registers has finished */
  35. rtc_lwoff_wait();
  36. /* change the current time */
  37. rtc_counter_set(utc_s);
  38. rtc_lwoff_wait();
  39. }
  40. static void gd32_rtc_first_init(void){
  41. //keep rtc running and inited while chip reset
  42. if (gd32_bkp_first_startup()){
  43. /* enable PMU and BKPI clocks */
  44. rcu_periph_clock_enable(RCU_BKPI);
  45. rcu_periph_clock_enable(RCU_PMU);
  46. /* allow access to BKP domain */
  47. pmu_backup_write_enable();
  48. /* reset backup domain */
  49. bkp_deinit();
  50. rcu_osci_on(RCU_IRC40K);
  51. rcu_osci_stab_wait(RCU_IRC40K);
  52. /* select RCU_RTCSRC_IRC40K as RTC clock source */
  53. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  54. /* enable RTC Clock */
  55. rcu_periph_clock_enable(RCU_RTC);
  56. /* wait for RTC registers synchronization */
  57. rtc_register_sync_wait();
  58. /* wait until last write operation on RTC registers has finished */
  59. rtc_lwoff_wait();
  60. rtc_interrupt_enable(RTC_INT_SECOND);
  61. /* wait until last write operation on RTC registers has finished */
  62. rtc_lwoff_wait();
  63. //set 1s a tick
  64. rtc_prescaler_set(40000-1);
  65. /* wait until last write operation on RTC registers has finished */
  66. rtc_lwoff_wait();
  67. bkp_write_data(POWER_FIRSTFLAG_REG, POWER_FIRSTFLAG_VALUE);
  68. }else{
  69. /* allow access to BKP domain */
  70. rcu_periph_clock_enable(RCU_PMU);
  71. pmu_backup_write_enable();
  72. rcu_osci_on(RCU_IRC40K);
  73. rcu_osci_stab_wait(RCU_IRC40K);
  74. /* select RCU_RTCSRC_IRC40K as RTC clock source */
  75. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  76. /* enable RTC Clock */
  77. rcu_periph_clock_enable(RCU_RTC);
  78. /* wait for RTC registers synchronization */
  79. rtc_register_sync_wait();
  80. rtc_lwoff_wait();
  81. /* enable the RTC second and alarm interrupt*/
  82. rtc_interrupt_enable(RTC_INT_SECOND);
  83. rtc_lwoff_wait();
  84. }
  85. }
  86. static void gd32_rtc_enable_second_irq(int enable){
  87. if (enable){
  88. nvic_irq_enable(RTC_IRQn, RTC_IRQ_PRIORITY, 0U);
  89. }else{
  90. nvic_irq_disable(RTC_IRQn);
  91. }
  92. }
  93. void gd32_rtc_init(void){
  94. gd32_rtc_first_init();
  95. //3?¡§o?¡§o?¨¤1??¨¤?RTC alarm¡§o?3?
  96. gd32_rtc_stop_alarm();
  97. #ifdef GD32F30X_CL
  98. nvic_irq_disable(RTC_ALARM_IRQn);
  99. #else
  100. nvic_irq_disable(RTC_Alarm_IRQn);
  101. #endif
  102. exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
  103. exti_flag_clear(EXTI_17);
  104. exti_interrupt_enable(EXTI_17);
  105. gd32_rtc_enable_second_irq(1);
  106. }
  107. int rtc_lwoff_wait_timeout(void)
  108. {
  109. int wait_count = 0xffff;
  110. /* loop until LWOFF flag is set */
  111. while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){
  112. if (wait_count -- <= 0){
  113. return -1;
  114. }
  115. }
  116. return 0;
  117. }
  118. static int set_rtc_alarm(uint32_t sencod){
  119. uint32_t current_count=0;
  120. do {
  121. current_count = rtc_counter_get();
  122. }while(current_count != rtc_counter_get());
  123. rtc_alarm_config(current_count + sencod);
  124. return rtc_lwoff_wait_timeout();
  125. }
  126. int gd32_rtc_start_alarm(uint32_t second){
  127. #ifdef GD32F30X_CL
  128. nvic_irq_enable(RTC_ALARM_IRQn, RTC_IRQ_PRIORITY, 0U);
  129. #else
  130. nvic_irq_enable(RTC_Alarm_IRQn, RTC_IRQ_PRIORITY, 0U);
  131. #endif
  132. exti_flag_clear(EXTI_17);
  133. exti_interrupt_enable(EXTI_17);
  134. rtc_register_sync_wait();
  135. rtc_flag_clear(RTC_FLAG_ALARM);
  136. rtc_lwoff_wait();
  137. rtc_interrupt_enable(RTC_INT_ALARM);// second means a shot here
  138. rtc_lwoff_wait();
  139. return set_rtc_alarm(second);
  140. }
  141. void gd32_rtc_stop_alarm(void){
  142. exti_interrupt_disable(EXTI_17);
  143. rtc_flag_clear(RTC_FLAG_ALARM);
  144. rtc_lwoff_wait();
  145. rtc_interrupt_disable(RTC_INT_ALARM);
  146. rtc_lwoff_wait();
  147. }
  148. int gd32_rtc_update_alarm(uint32_t sencod){
  149. return set_rtc_alarm(sencod);
  150. }
  151. uint32_t rtc_irq_times = 0;
  152. static alarm_handler s_handler = NULL;
  153. void gd32_rtc_set_alarm_handler(alarm_handler handler){
  154. s_handler = handler;
  155. }
  156. void RTC_Alarm_IRQHandler(void)
  157. {
  158. if (rtc_flag_get(RTC_FLAG_ALARM) != RESET)
  159. {
  160. /* clear the RTC second interrupt flag*/
  161. rtc_flag_clear(RTC_FLAG_ALARM);
  162. if (s_handler != NULL){
  163. s_handler();
  164. }
  165. rtc_irq_times++;
  166. }
  167. exti_interrupt_flag_clear(EXTI_17);
  168. }
  169. void RTC_IRQHandler(void){
  170. if (rtc_flag_get(RTC_FLAG_OVERFLOW /*RTC_INT_FLAG_OVERFLOW*/) != RESET)
  171. {
  172. /* clear the RTC overflow interrupt flag*/
  173. rtc_flag_clear(RTC_FLAG_OVERFLOW);
  174. }
  175. if (rtc_flag_get(RTC_FLAG_SECOND) != RESET)
  176. {
  177. rtc_second++;
  178. /* clear the RTC second interrupt flag*/
  179. rtc_flag_clear(RTC_FLAG_SECOND);
  180. }
  181. }