luat_gnss.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #include "luat_base.h"
  2. #include "luat_msgbus.h"
  3. #include "luat_malloc.h"
  4. #include "luat_uart.h"
  5. #include "luat_rtc.h"
  6. #include "luat_mcu.h"
  7. #define LUAT_LOG_TAG "gnss"
  8. #include "luat_log.h"
  9. #include "minmea.h"
  10. luat_libgnss_t *libgnss_gnss;
  11. luat_libgnss_tmp_t *libgnss_gnsstmp;
  12. char *libgnss_recvbuff;
  13. int libgnss_route_uart_id = -1;
  14. int gnss_debug = 0;
  15. // static int parse_nmea(const char* line);
  16. // static int parse_data(const char* data, size_t len);
  17. void luat_libgnss_uart_recv_cb(int uart_id, uint32_t data_len) {
  18. (void)data_len;
  19. if (libgnss_recvbuff == NULL)
  20. return;
  21. //LLOGD("uart recv cb");
  22. int len = 0;
  23. while (1) {
  24. len = luat_uart_read(uart_id, libgnss_recvbuff, RECV_BUFF_SIZE - 1);
  25. if (len < 1 || len >= RECV_BUFF_SIZE)
  26. break;
  27. if (libgnss_route_uart_id > 0) {
  28. luat_uart_write(libgnss_route_uart_id, libgnss_recvbuff, len);
  29. }
  30. luat_libgnss_on_rawdata(libgnss_recvbuff, len);
  31. libgnss_recvbuff[len] = 0;
  32. if (libgnss_gnss == NULL)
  33. continue;
  34. // LLOGD("uart recv %d %d", len, gnss_debug);
  35. if (gnss_debug) {
  36. LLOGD(">> %s", libgnss_recvbuff);
  37. }
  38. luat_libgnss_parse_data(libgnss_recvbuff, len);
  39. }
  40. }
  41. // static uint32_t msg_counter[MINMEA_SENTENCE_MAX_ID];
  42. int luat_libgnss_init(int clear) {
  43. if (libgnss_gnss == NULL) {
  44. libgnss_gnss = luat_heap_malloc(sizeof(luat_libgnss_t));
  45. if (libgnss_gnss == NULL) {
  46. LLOGW("out of memory for libgnss data parse");
  47. return -1;
  48. }
  49. }
  50. if (libgnss_gnsstmp == NULL) {
  51. libgnss_gnsstmp = luat_heap_malloc(sizeof(luat_libgnss_tmp_t));
  52. if (libgnss_gnsstmp == NULL) {
  53. luat_heap_free(libgnss_gnss);
  54. libgnss_gnss = NULL;
  55. LLOGW("out of memory for libgnss data parse");
  56. return -1;
  57. }
  58. }
  59. // gnss->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  60. if (clear) {
  61. memset(libgnss_gnss, 0, sizeof(luat_libgnss_t));
  62. memset(libgnss_gnsstmp, 0, sizeof(luat_libgnss_tmp_t));
  63. }
  64. //lua_pushboolean(L, 1);
  65. return 0;
  66. }
  67. int luat_libgnss_parse_data(const char* data, size_t len) {
  68. size_t prev = 0;
  69. #define MAX_LEN (120)
  70. static char nmea_tmp_buff[MAX_LEN] = {0}; // nmea 最大长度82,含换行符
  71. // if (data[0] == 0xAA && data[1] == 0xF0) {
  72. // LLOGD("EPH data resp?");
  73. // }
  74. for (size_t offset = 0; offset < len; offset++)
  75. {
  76. // \r == 0x0D \n == 0x0A
  77. if (data[offset] == 0x0A) {
  78. // 最短也需要是 OK\r\n
  79. // 应该\r\n的
  80. // 太长了
  81. if (offset - prev < 3 || data[offset - 1] != 0x0D || offset - prev > 82) {
  82. prev = offset + 1;
  83. continue;
  84. }
  85. if (offset - prev - 1 < MAX_LEN) {
  86. memcpy(nmea_tmp_buff, data + prev, offset - prev - 1);
  87. nmea_tmp_buff[offset - prev - 1] = 0x00;
  88. // if (gnss_debug) {
  89. // LLOGD(">> %s", nmea_tmp_buff);
  90. // }
  91. luat_libgnss_parse_nmea((const char*)nmea_tmp_buff);
  92. }
  93. else {
  94. // 超长了, 忽略
  95. }
  96. prev = offset + 1;
  97. }
  98. }
  99. return 0;
  100. }
  101. int luat_libgnss_parse_nmea(const char* line) {
  102. if (libgnss_gnss == NULL && luat_libgnss_init(0)) {
  103. return 0;
  104. }
  105. struct minmea_sentence_gsv *frame_gsv = &libgnss_gnsstmp->frame_gsv;
  106. enum minmea_sentence_id id = minmea_sentence_id(line, false);
  107. if (id == MINMEA_UNKNOWN || id >= MINMEA_SENTENCE_MAX_ID || id == MINMEA_INVALID)
  108. return -1;
  109. // msg_counter[id] ++;
  110. // int ticks = 0;
  111. struct tm tblock = {0};
  112. int ticks = luat_mcu_ticks();
  113. switch (id) {
  114. case MINMEA_SENTENCE_RMC: {
  115. if (minmea_parse_rmc(&(libgnss_gnsstmp->frame_rmc), line)) {
  116. // 清空gsa
  117. memset(libgnss_gnss->frame_gsa, 0, sizeof(struct minmea_sentence_gsa) * FRAME_GSA_MAX);
  118. if (libgnss_gnsstmp->frame_rmc.valid) {
  119. memcpy(&(libgnss_gnss->frame_rmc), &libgnss_gnsstmp->frame_rmc, sizeof(struct minmea_sentence_rmc));
  120. #ifdef LUAT_USE_MCU
  121. if (libgnss_gnss->rtc_auto && (libgnss_gnss->fix_at_ticks == 0 || ((uint32_t)(ticks - libgnss_gnss->fix_at_ticks)) > 600*1000)) {
  122. LLOGI("Auto-Set RTC by GNSS RMC");
  123. minmea_getdatetime(&tblock, &libgnss_gnss->frame_rmc.date, &libgnss_gnss->frame_rmc.time);
  124. tblock.tm_year -= 1900;
  125. luat_rtc_set(&tblock);
  126. // luat_rtc_set_tamp32(mktime(&tblock));
  127. }
  128. if (libgnss_gnss->fix_at_ticks == 0) {
  129. LLOGI("Fixed %d %d", libgnss_gnss->frame_rmc.latitude.value, libgnss_gnss->frame_rmc.longitude.value);
  130. // 发布系统消息
  131. luat_libgnss_state_onchanged(GNSS_STATE_FIXED);
  132. }
  133. libgnss_gnss->fix_at_ticks = luat_mcu_ticks();
  134. #endif
  135. }
  136. else {
  137. if (libgnss_gnss->fix_at_ticks && libgnss_gnss->frame_rmc.valid) {
  138. LLOGI("Lose"); // 发布系统消息
  139. luat_libgnss_state_onchanged(GNSS_STATE_LOSE);
  140. }
  141. libgnss_gnss->fix_at_ticks = 0;
  142. libgnss_gnss->frame_rmc.valid = 0;
  143. if (libgnss_gnsstmp->frame_rmc.date.year > 0) {
  144. memcpy(&(libgnss_gnss->frame_rmc.date), &(libgnss_gnsstmp->frame_rmc.date), sizeof(struct minmea_date));
  145. }
  146. if (libgnss_gnsstmp->frame_rmc.time.hours > 0) {
  147. memcpy(&(libgnss_gnss->frame_rmc.time), &(libgnss_gnsstmp->frame_rmc.time), sizeof(struct minmea_time));
  148. }
  149. }
  150. }
  151. } break;
  152. case MINMEA_SENTENCE_GGA: {
  153. memcpy(libgnss_gnss->gga, line, strlen(line) + 1);
  154. } break;
  155. case MINMEA_SENTENCE_GSA: {
  156. //LLOGD("GSV %s", line);
  157. if (minmea_parse_gsa(&(libgnss_gnsstmp->frame_gsa), line)) {
  158. for (size_t i = 0; i < FRAME_GSA_MAX; i++)
  159. {
  160. // 如果是mode=0,代表空的
  161. if (libgnss_gnss->frame_gsa[i].mode == 0) {
  162. memcpy(&libgnss_gnss->frame_gsa[i], &(libgnss_gnsstmp->frame_gsa), sizeof(struct minmea_sentence_gsa));
  163. break;
  164. }
  165. }
  166. }
  167. } break;
  168. case MINMEA_SENTENCE_GLL: {
  169. memcpy(libgnss_gnss->gll, line, strlen(line) + 1);
  170. } break;
  171. case MINMEA_SENTENCE_GST: {
  172. memcpy(libgnss_gnss->gst, line, strlen(line) + 1);
  173. } break;
  174. case MINMEA_SENTENCE_GSV: {
  175. //LLOGD("Got GSV : %s", line);
  176. if (minmea_parse_gsv(frame_gsv, line)) {
  177. struct minmea_sentence_gsv *gsvs = libgnss_gnss->frame_gsv_gp;
  178. if (0 == memcmp("$GPGSV", line, strlen("$GPGSV"))) {
  179. gsvs = libgnss_gnss->frame_gsv_gp;
  180. }
  181. else if (0 == memcmp("$GBGSV", line, strlen("$GBGSV"))) {
  182. gsvs = libgnss_gnss->frame_gsv_gb;
  183. }
  184. // else if (0 == memcmp("$GLGSV", line, strlen("$GLGSV"))) {
  185. // gsvs = libgnss_gnss->frame_gsv_gl;
  186. // }
  187. // else if (0 == memcmp("$GAGSV", line, strlen("$GAGSV"))) {
  188. // gsvs = libgnss_gnss->frame_gsv_ga;
  189. // }
  190. else {
  191. break;
  192. }
  193. //LLOGD("$GSV: message %d of %d", frame_gsv.msg_nr, frame_gsv.total_msgs);
  194. if (frame_gsv->msg_nr == 1) {
  195. //LLOGD("Clean GSV");
  196. memset(gsvs, 0, sizeof(struct minmea_sentence_gsv) * FRAME_GSV_MAX);
  197. }
  198. if (frame_gsv->msg_nr >= 1 && frame_gsv->msg_nr <= FRAME_GSV_MAX) {
  199. //LLOGD("memcpy GSV %d", frame_gsv.msg_nr);
  200. memcpy(&gsvs[frame_gsv->msg_nr - 1], frame_gsv, sizeof(struct minmea_sentence_gsv));
  201. }
  202. }
  203. else {
  204. //LLOGD("bad GSV %s", line);
  205. }
  206. } break;
  207. case MINMEA_SENTENCE_VTG: {
  208. memcpy(libgnss_gnss->vtg, line, strlen(line) + 1);
  209. } break;
  210. case MINMEA_SENTENCE_ZDA: {
  211. memcpy(libgnss_gnss->zda, line, strlen(line) + 1);
  212. } break;
  213. default:
  214. //LLOGD("why happen");
  215. break;
  216. }
  217. return 0;
  218. }