ql_rtc_demo.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /**
  2. @file
  3. ql_rtc_demo.c
  4. @brief
  5. quectel rtc demo.
  6. */
  7. /*================================================================
  8. Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
  9. Quectel Wireless Solution Proprietary and Confidential.
  10. =================================================================*/
  11. /*=================================================================
  12. EDIT HISTORY FOR MODULE
  13. This section contains comments describing changes made to the module.
  14. Notice that changes are listed in reverse chronological order.
  15. WHEN WHO WHAT, WHERE, WHY
  16. ------------ ------- -------------------------------------------------------------------------------
  17. 16/12/2020 Neo Init version
  18. =================================================================*/
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include "ql_api_osi.h"
  23. #include "ql_log.h"
  24. #include "ql_api_rtc.h"
  25. #include "ql_rtc_demo.h"
  26. /*===========================================================================
  27. * Macro Definition
  28. ===========================================================================*/
  29. #define QL_RTCDEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
  30. #define QL_RTCDEMO_LOG(msg, ...) QL_LOG(QL_RTCDEMO_LOG_LEVEL, "ql_RTCDEMO", msg, ##__VA_ARGS__)
  31. #define QL_RTCDEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_RTCDEMO", msg, ##__VA_ARGS__)
  32. #define leapyear(year) ((year) % 4 == 0)
  33. #define days_in_year(a) (leapyear(a) ? 366 : 365)
  34. #define days_in_month(a) (month_days[(a) - 1])
  35. #define FEBRUARY 2
  36. #define STARTOFTIME 1970
  37. #define SECDAY 86400L
  38. #define SECYR (SECDAY * 365)
  39. #if !defined(rtc_demo_err_exit)
  40. #define rtc_demo_err_exit(x, action, str) \
  41. do \
  42. { \
  43. if(x) \
  44. { \
  45. QL_RTCDEMO_LOG(str); \
  46. {goto action;} \
  47. } \
  48. } while( 1==0 )
  49. #endif
  50. /*========================================================================
  51. * Global Variable
  52. *========================================================================*/
  53. static int month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  54. /*========================================================================
  55. * function Definition
  56. *========================================================================*/
  57. static int ql_rtc_fix_weekday(ql_rtc_time_t *rtc_time)
  58. {
  59. int leapsToDate;
  60. int lastYear;
  61. int day;
  62. int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
  63. if (rtc_time->tm_year < 1753)
  64. return -1;
  65. lastYear=rtc_time->tm_year-1;
  66. //Number of leap corrections to apply up to end of last year
  67. leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
  68. //This year is a leap year if it is divisible by 4 except when it is divisible by 100 unless it is divisible by 400
  69. //e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
  70. if((rtc_time->tm_year%4==0) && ((rtc_time->tm_year%100!=0) || (rtc_time->tm_year%400==0)) && (rtc_time->tm_mon>2))
  71. {
  72. //We are past Feb. 29 in a leap year
  73. day=1;
  74. }
  75. else
  76. {
  77. day=0;
  78. }
  79. day += lastYear*365 + leapsToDate + MonthOffset[rtc_time->tm_mon-1] + rtc_time->tm_mday;
  80. rtc_time->tm_wday=day%7;
  81. return 0;
  82. }
  83. static int ql_sec_conv_rtc_time(int64_t* time_t, ql_rtc_time_t *rtc_time)
  84. {
  85. int i;
  86. long hms, day;
  87. day = *time_t / SECDAY;
  88. hms = *time_t % SECDAY;
  89. //Hours, minutes, seconds are easy
  90. rtc_time->tm_hour = hms / 3600;
  91. rtc_time->tm_min = (hms % 3600) / 60;
  92. rtc_time->tm_sec = (hms % 3600) % 60;
  93. //Number of years in days
  94. for (i = STARTOFTIME; day >= days_in_year(i); i++)
  95. {
  96. day -= days_in_year(i);
  97. }
  98. rtc_time->tm_year = i;
  99. //Number of months in days left
  100. if (leapyear(rtc_time->tm_year))
  101. {
  102. days_in_month(FEBRUARY) = 29;
  103. }
  104. for (i = 1; day >= days_in_month(i); i++)
  105. {
  106. day -= days_in_month(i);
  107. }
  108. days_in_month(FEBRUARY) = 28;
  109. rtc_time->tm_mon = i;
  110. //Days are what is left over (+1) from all that.
  111. rtc_time->tm_mday = day + 1;
  112. //Determine the day of week
  113. return ql_rtc_fix_weekday(rtc_time);
  114. }
  115. static int ql_rtc_conv_sec_time(int64_t* time_t, ql_rtc_time_t* rtc_time)
  116. {
  117. int mon = rtc_time->tm_mon;
  118. int year = rtc_time->tm_year;
  119. int64_t days, hours;
  120. mon -= 2;
  121. if (0 >= (int)mon)
  122. {
  123. // 1..12 -> 11,12,1..10
  124. mon += 12;
  125. //Puts Feb last since it has leap day
  126. year -= 1;
  127. }
  128. days = (unsigned long)(year / 4 - year / 100 + year / 400 +367 * mon / 12 + rtc_time->tm_mday) + year * 365 - 719499;
  129. hours = (days * 24) + rtc_time->tm_hour;
  130. *time_t = (hours * 60 + rtc_time->tm_min) * 60 + rtc_time->tm_sec;
  131. return 0;
  132. }
  133. void ql_rtc_test_callback(void)
  134. {
  135. QL_RTCDEMO_LOG("ql rtc test callback come in!");
  136. ql_rtc_time_t test_tm = {0};
  137. //disable RTC alarm
  138. //ql_rtc_enable_alarm(0);
  139. //get alarm time
  140. QL_RTCDEMO_LOG("=========callback print alarm time===========\r\n");
  141. ql_rtc_get_alarm(&test_tm);
  142. ql_rtc_print_time(test_tm);
  143. }
  144. static void ql_rtc_demo_thread()
  145. {
  146. ql_rtc_time_t tm;
  147. int64_t time_t;
  148. QlOSStatus err = QL_OSI_SUCCESS;
  149. ql_errcode_rtc_e ret;
  150. int timezone_value = 0;
  151. //get current time
  152. ret = ql_rtc_get_time(&tm);
  153. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "get time err");
  154. ret =ql_rtc_print_time(tm);
  155. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "print time err");
  156. ql_rtc_conv_sec_time(&time_t, &tm);
  157. QL_RTCDEMO_LOG("getting time convert %ld sec.\r\n",time_t);
  158. ql_sec_conv_rtc_time(&time_t, &tm);
  159. ret =ql_rtc_print_time(tm);
  160. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "print time err");
  161. //2021-6-15 16:50:30 [TUS]
  162. tm.tm_year = 2021;
  163. tm.tm_mon = 6;
  164. tm.tm_mday = 22;
  165. tm.tm_wday = 4;
  166. tm.tm_hour = 16;
  167. tm.tm_min = 50;
  168. tm.tm_sec = 30;
  169. ret = ql_rtc_print_time(tm);
  170. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "print time err");
  171. //set time
  172. ret = ql_rtc_set_time(&tm);
  173. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "set time err");
  174. ret = ql_rtc_get_time(&tm);
  175. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "get time err");
  176. ret = ql_rtc_print_time(tm);
  177. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "print time err");
  178. //set & enable alarm
  179. tm.tm_sec += 20;
  180. ret = ql_rtc_set_alarm(&tm);
  181. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "set alarm err");
  182. ret = ql_rtc_register_cb(ql_rtc_test_callback);
  183. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "reg cb err");
  184. ret = ql_rtc_enable_alarm(1);
  185. rtc_demo_err_exit(ret != QL_RTC_SUCCESS, QL_RTC_DEMO_EXIT, "enable alarm err");
  186. while (1)
  187. {
  188. ql_rtc_get_time(&tm);
  189. QL_RTCDEMO_LOG("=========print current time===========\r\n");
  190. ql_rtc_print_time(tm);
  191. ql_rtc_set_timezone(32); //UTC+32
  192. ql_rtc_get_localtime(&tm);
  193. QL_RTCDEMO_LOG("=========print local time===========\r\n");
  194. ql_rtc_print_time(tm);
  195. ql_rtc_get_timezone(&timezone_value);
  196. QL_RTCDEMO_LOG("timezone_value: %+03d\r\n", timezone_value);
  197. ql_rtos_task_sleep_s(5);
  198. }
  199. QL_RTC_DEMO_EXIT:
  200. err = ql_rtos_task_delete(NULL);
  201. if(err != QL_OSI_SUCCESS)
  202. {
  203. QL_RTCDEMO_LOG("task deleted failed");
  204. }
  205. }
  206. void ql_rtc_app_init()
  207. {
  208. QlOSStatus err = QL_OSI_SUCCESS;
  209. ql_task_t rtc_task = NULL;
  210. err = ql_rtos_task_create(&rtc_task, 1024, APP_PRIORITY_NORMAL, "ql_rtcdemo", ql_rtc_demo_thread, NULL, 1);
  211. if( err != QL_OSI_SUCCESS )
  212. {
  213. QL_RTCDEMO_LOG("rtc demo task created failed");
  214. }
  215. }