shark_rtc.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <string.h>
  4. //#include "gd32e10x.h"
  5. //#include "gd32e103v_eval.h"
  6. #include "Gd32f30x_rtc.h"
  7. #include "Gd32f30x_bkp.h"
  8. #include "qws_status.h"
  9. #include "shark_rtc.h"
  10. #include "FreeRTOS.h"
  11. #include "task.h"
  12. #include "shark_bkp.h"
  13. #define IS_LEAP_YEAR(year) ((year % 4 == 0) && ( year % 100 != 0) || (year % 400 == 0))
  14. static uint32_t time_ticks = 0;
  15. #define POWER_FIRSTFLAG_REG BKP_DATA_0
  16. #define POWER_FIRSTFLAG_VALUE 0x5AA5
  17. unsigned char check_rtc_time()
  18. {
  19. int rtcTime = rtc_counter_get();
  20. if(rtcTime > YEAR_20171201_UTS && rtcTime < YEAR_20571201_UTS)
  21. return 1;
  22. start_uptade_local_time();
  23. return 0;
  24. }
  25. uint32_t app_getcurrtime_utc(void)
  26. {
  27. if(check_rtc_time() == 1)
  28. return shark_rtc_get_timestamp();
  29. else
  30. return 0;
  31. }
  32. /* get the utc readable time */
  33. void shark_rtc_get_local_time(uint32_t second, time_val *out){
  34. struct tm *tm;
  35. tm = localtime((time_t *)&second);
  36. out->year = tm->tm_year + 1900;
  37. out->month = tm->tm_mon + 1;
  38. out->day = tm->tm_mday;
  39. out->hour = tm->tm_hour;
  40. out->minute = tm->tm_min;
  41. out->second = tm->tm_sec;
  42. }
  43. /* get utc timestamp --> second */
  44. uint32_t shark_rtc_get_timestamp(void){
  45. return rtc_counter_get();
  46. }
  47. /*tz quarter-hour ,15min ,-48~+48*/
  48. uint32_t shark_rtc_get_timestamp_with_time_zone(int8_t tz){
  49. return (rtc_counter_get()+ tz*15*60);
  50. }
  51. void shark_rtc_getcurrtime_loca_time(time_val*ltc)
  52. {
  53. if(ltc==NULL) return;
  54. shark_rtc_get_local_time(shark_rtc_get_timestamp_with_time_zone(qws_status_get()->bike.qws_TZ ),ltc);
  55. }
  56. /* get utc timestamp --> macro second */
  57. uint64_t shark_rtc_get_timestamp_ms(void){
  58. return (uint64_t)rtc_counter_get() * 1000 + ((xTaskGetTickCount() - time_ticks) / portTICK_RATE_MS)%(1000/portTICK_RATE_MS);
  59. }
  60. /* set rtc time, used utc timestamp, can not include time zone*/
  61. uint32_t calendar_to_utc(time_val *time){
  62. struct tm utc_time;
  63. struct tm my_time;
  64. memset(&utc_time, 0, sizeof (struct tm));
  65. memset(&my_time, 0, sizeof (struct tm));
  66. my_time.tm_mday = time->day;
  67. my_time.tm_mon = time->month- 1;
  68. my_time.tm_year = time->year - 1900;
  69. my_time.tm_hour = time->hour;
  70. my_time.tm_min = time->minute;
  71. my_time.tm_sec = time->second;
  72. utc_time.tm_mday = 1;
  73. utc_time.tm_mon = 1 - 1;
  74. utc_time.tm_year = 1970 - 1900;
  75. utc_time.tm_hour = 0;
  76. utc_time.tm_min = 0;
  77. utc_time.tm_sec = 0;
  78. return mktime(&my_time) - mktime(&utc_time);
  79. }
  80. void shark_rtc_set_time(time_val *time){
  81. uint32_t second = calendar_to_utc(time);
  82. /* wait until last write operation on RTC registers has finished */
  83. rtc_lwoff_wait();
  84. /* change the current time */
  85. rtc_counter_set(second);
  86. rtc_lwoff_wait();
  87. }
  88. void shark_rtc_set_time_with_utc_second(uint32_t utc_s){
  89. /* wait until last write operation on RTC registers has finished */
  90. rtc_lwoff_wait();
  91. /* change the current time */
  92. rtc_counter_set(utc_s);
  93. rtc_lwoff_wait();
  94. }
  95. static void shark_rtc_first_init(void){
  96. //keep rtc running and inited while chip reset
  97. if (shark_bkp_first_startup()){
  98. /* enable PMU and BKPI clocks */
  99. rcu_periph_clock_enable(RCU_BKPI);
  100. rcu_periph_clock_enable(RCU_PMU);
  101. /* allow access to BKP domain */
  102. pmu_backup_write_enable();
  103. /* reset backup domain */
  104. bkp_deinit();
  105. rcu_osci_on(RCU_IRC40K);
  106. rcu_osci_stab_wait(RCU_IRC40K);
  107. /* select RCU_RTCSRC_IRC40K as RTC clock source */
  108. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  109. /* enable RTC Clock */
  110. rcu_periph_clock_enable(RCU_RTC);
  111. /* wait for RTC registers synchronization */
  112. rtc_register_sync_wait();
  113. /* wait until last write operation on RTC registers has finished */
  114. rtc_lwoff_wait();
  115. rtc_interrupt_enable(RTC_INT_SECOND);
  116. /* wait until last write operation on RTC registers has finished */
  117. rtc_lwoff_wait();
  118. //set 1s a tick
  119. rtc_prescaler_set(40000-1);
  120. /* wait until last write operation on RTC registers has finished */
  121. rtc_lwoff_wait();
  122. bkp_write_data(POWER_FIRSTFLAG_REG, POWER_FIRSTFLAG_VALUE);
  123. }else{
  124. /* allow access to BKP domain */
  125. rcu_periph_clock_enable(RCU_PMU);
  126. pmu_backup_write_enable();
  127. rcu_osci_on(RCU_IRC40K);
  128. rcu_osci_stab_wait(RCU_IRC40K);
  129. /* select RCU_RTCSRC_IRC40K as RTC clock source */
  130. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  131. /* enable RTC Clock */
  132. rcu_periph_clock_enable(RCU_RTC);
  133. /* wait for RTC registers synchronization */
  134. rtc_register_sync_wait();
  135. rtc_lwoff_wait();
  136. /* enable the RTC second and alarm interrupt*/
  137. rtc_interrupt_enable(RTC_INT_SECOND);
  138. rtc_lwoff_wait();
  139. }
  140. }
  141. static void shark_rtc_enable_second_irq(int enable){
  142. if (enable){
  143. nvic_irq_enable(RTC_IRQn, 2U, 0U);
  144. }else{
  145. nvic_irq_disable(RTC_IRQn);
  146. }
  147. }
  148. void shark_rtc_init(void){
  149. shark_rtc_first_init();
  150. nvic_irq_enable(RTC_Alarm_IRQn , 2U, 0U);
  151. exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
  152. exti_flag_clear(EXTI_17);
  153. exti_interrupt_enable(EXTI_17);
  154. shark_rtc_enable_second_irq(1);
  155. }
  156. int rtc_lwoff_wait_timeout(void)
  157. {
  158. int wait_count = 0xffff;
  159. /* loop until LWOFF flag is set */
  160. while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){
  161. if (wait_count -- <= 0){
  162. return -1;
  163. }
  164. }
  165. return 0;
  166. }
  167. static int set_rtc_alarm(uint32_t sencod){
  168. uint32_t current_count=0;
  169. current_count = rtc_counter_get();
  170. //rtc_lwoff_wait();
  171. rtc_alarm_config(current_count + sencod);
  172. return rtc_lwoff_wait_timeout();
  173. }
  174. int shark_rtc_start_alarm(uint32_t second){
  175. rtc_lwoff_wait();
  176. rtc_interrupt_enable(RTC_INT_ALARM);// second means a shot here
  177. rtc_lwoff_wait();
  178. rtc_flag_clear(RTC_INT_SECOND ); //RTC_INT_FLAG_SECOND
  179. rtc_lwoff_wait();
  180. rtc_interrupt_disable(RTC_INT_SECOND);
  181. rtc_lwoff_wait();
  182. return set_rtc_alarm(second);
  183. }
  184. void shark_rtc_stop_alarm(void){
  185. rtc_lwoff_wait();
  186. rtc_interrupt_disable(RTC_INT_ALARM);
  187. rtc_lwoff_wait();
  188. rtc_interrupt_enable(RTC_INT_SECOND);
  189. rtc_lwoff_wait();
  190. }
  191. void shark_rtc_update_alarm(uint32_t sencod){
  192. set_rtc_alarm(sencod);
  193. }
  194. uint32_t qws_rtc_irq_times = 0;
  195. static alarm_handler s_handler = NULL;
  196. void shark_rtc_set_alarm_handler(alarm_handler handler){
  197. s_handler = handler;
  198. }
  199. void RTC_Alarm_IRQHandler(void)
  200. {
  201. if (rtc_flag_get(RTC_INT_ALARM) != RESET)
  202. {
  203. /* clear the RTC second interrupt flag*/
  204. rtc_flag_clear(RTC_INT_ALARM);
  205. if (s_handler != NULL){
  206. s_handler();
  207. }
  208. qws_rtc_irq_times++;
  209. }
  210. exti_interrupt_flag_clear(EXTI_17);
  211. }
  212. void RTC_IRQHandler(void){
  213. if (rtc_flag_get(RTC_INT_OVERFLOW /*RTC_INT_FLAG_OVERFLOW*/) != RESET)
  214. {
  215. /* clear the RTC overflow interrupt flag*/
  216. rtc_flag_clear(RTC_INT_OVERFLOW);
  217. }
  218. if (rtc_flag_get(RTC_INT_SECOND) != RESET)
  219. {
  220. time_ticks = xTaskGetTickCount();
  221. /* clear the RTC second interrupt flag*/
  222. rtc_flag_clear(RTC_INT_SECOND);
  223. }
  224. }