gd32_rtc.c 5.0 KB

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