gd32_rtc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. nvic_irq_disable(RTC_Alarm_IRQn);
  98. exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
  99. exti_flag_clear(EXTI_17);
  100. exti_interrupt_enable(EXTI_17);
  101. gd32_rtc_enable_second_irq(1);
  102. }
  103. int rtc_lwoff_wait_timeout(void)
  104. {
  105. int wait_count = 0xffff;
  106. /* loop until LWOFF flag is set */
  107. while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){
  108. if (wait_count -- <= 0){
  109. return -1;
  110. }
  111. }
  112. return 0;
  113. }
  114. static int set_rtc_alarm(uint32_t sencod){
  115. uint32_t current_count=0;
  116. do {
  117. current_count = rtc_counter_get();
  118. }while(current_count != rtc_counter_get());
  119. rtc_alarm_config(current_count + sencod);
  120. return rtc_lwoff_wait_timeout();
  121. }
  122. int gd32_rtc_start_alarm(uint32_t second){
  123. nvic_irq_enable(RTC_Alarm_IRQn, RTC_IRQ_PRIORITY, 0U);
  124. exti_flag_clear(EXTI_17);
  125. exti_interrupt_enable(EXTI_17);
  126. rtc_register_sync_wait();
  127. rtc_flag_clear(RTC_FLAG_ALARM);
  128. rtc_lwoff_wait();
  129. rtc_interrupt_enable(RTC_INT_ALARM);// second means a shot here
  130. rtc_lwoff_wait();
  131. return set_rtc_alarm(second);
  132. }
  133. void gd32_rtc_stop_alarm(void){
  134. exti_interrupt_disable(EXTI_17);
  135. rtc_flag_clear(RTC_FLAG_ALARM);
  136. rtc_lwoff_wait();
  137. rtc_interrupt_disable(RTC_INT_ALARM);
  138. rtc_lwoff_wait();
  139. }
  140. int gd32_rtc_update_alarm(uint32_t sencod){
  141. return set_rtc_alarm(sencod);
  142. }
  143. uint32_t rtc_irq_times = 0;
  144. static alarm_handler s_handler = NULL;
  145. void gd32_rtc_set_alarm_handler(alarm_handler handler){
  146. s_handler = handler;
  147. }
  148. void RTC_Alarm_IRQHandler(void)
  149. {
  150. if (rtc_flag_get(RTC_FLAG_ALARM) != RESET)
  151. {
  152. /* clear the RTC second interrupt flag*/
  153. rtc_flag_clear(RTC_FLAG_ALARM);
  154. if (s_handler != NULL){
  155. s_handler();
  156. }
  157. rtc_irq_times++;
  158. }
  159. exti_interrupt_flag_clear(EXTI_17);
  160. }
  161. void RTC_IRQHandler(void){
  162. if (rtc_flag_get(RTC_FLAG_OVERFLOW /*RTC_INT_FLAG_OVERFLOW*/) != RESET)
  163. {
  164. /* clear the RTC overflow interrupt flag*/
  165. rtc_flag_clear(RTC_FLAG_OVERFLOW);
  166. }
  167. if (rtc_flag_get(RTC_FLAG_SECOND) != RESET)
  168. {
  169. rtc_second++;
  170. /* clear the RTC second interrupt flag*/
  171. rtc_flag_clear(RTC_FLAG_SECOND);
  172. }
  173. }