luat_gnss.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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_t *libgnss_gnsstmp;
  12. char *libgnss_recvbuff;
  13. // static int parse_nmea(const char* line);
  14. // static int parse_data(const char* data, size_t len);
  15. void luat_libgnss_uart_recv_cb(int uart_id, uint32_t data_len) {
  16. (void)data_len;
  17. if (libgnss_recvbuff == NULL)
  18. return;
  19. //LLOGD("uart recv cb");
  20. int len = 0;
  21. while (1) {
  22. len = luat_uart_read(uart_id, libgnss_recvbuff, RECV_BUFF_SIZE - 1);
  23. if (len < 1 || len > RECV_BUFF_SIZE)
  24. break;
  25. //LLOGD("uart recv %d", len);
  26. libgnss_recvbuff[len] = 0;
  27. if (libgnss_gnss == NULL)
  28. continue;
  29. if (libgnss_gnss->debug) {
  30. LLOGD("recv %s", libgnss_recvbuff);
  31. }
  32. luat_libgnss_parse_data(libgnss_recvbuff, len);
  33. }
  34. }
  35. static uint32_t msg_counter[MINMEA_SENTENCE_MAX_ID];
  36. int luat_libgnss_init(void) {
  37. if (libgnss_gnss == NULL) {
  38. libgnss_gnss = luat_heap_malloc(sizeof(luat_libgnss_t));
  39. if (libgnss_gnss == NULL) {
  40. LLOGW("out of memory for libgnss data parse");
  41. return 0;
  42. }
  43. libgnss_gnsstmp = luat_heap_malloc(sizeof(luat_libgnss_t));
  44. if (libgnss_gnsstmp == NULL) {
  45. luat_heap_free(libgnss_gnss);
  46. LLOGW("out of memory for libgnss data parse");
  47. return 0;
  48. }
  49. // gnss->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  50. memset(libgnss_gnss, 0, sizeof(luat_libgnss_t));
  51. memset(libgnss_gnsstmp, 0, sizeof(luat_libgnss_t));
  52. }
  53. //lua_pushboolean(L, 1);
  54. return 1;
  55. }
  56. int luat_libgnss_parse_data(const char* data, size_t len) {
  57. size_t prev = 0;
  58. static char nmea_tmp_buff[86] = {0}; // nmea 最大长度82,含换行符
  59. for (size_t offset = 0; offset < len; offset++)
  60. {
  61. // \r == 0x0D \n == 0x0A
  62. if (data[offset] == 0x0A) {
  63. // 最短也需要是 OK\r\n
  64. // 应该\r\n的
  65. // 太长了
  66. if (offset - prev < 3 || data[offset - 1] != 0x0D || offset - prev > 82) {
  67. prev = offset + 1;
  68. continue;
  69. }
  70. memcpy(nmea_tmp_buff, data + prev, offset - prev - 1);
  71. nmea_tmp_buff[offset - prev - 1] = 0x00;
  72. if (libgnss_gnss->debug) {
  73. LLOGD(">> %s", nmea_tmp_buff);
  74. }
  75. luat_libgnss_parse_nmea((const char*)nmea_tmp_buff);
  76. prev = offset + 1;
  77. }
  78. }
  79. return 0;
  80. }
  81. int luat_libgnss_parse_nmea(const char* line) {
  82. // $GNRMC,080313.00,A,2324.40756,N,11313.86184,E,0.284,,010720,,,A*68
  83. //if (gnss != NULL && gnss->debug)
  84. // LLOGD("GNSS [%s]", line);
  85. if (libgnss_gnss == NULL && !luat_libgnss_init()) {
  86. return 0;
  87. }
  88. struct minmea_sentence_gsv frame_gsv = {0};
  89. enum minmea_sentence_id id = minmea_sentence_id(line, false);
  90. if (id == MINMEA_UNKNOWN || id >= MINMEA_SENTENCE_MAX_ID || id == MINMEA_INVALID)
  91. return -1;
  92. msg_counter[id] ++;
  93. // int ticks = 0;
  94. struct tm tblock = {0};
  95. int ticks = luat_mcu_ticks();
  96. switch (id) {
  97. case MINMEA_SENTENCE_RMC: {
  98. if (minmea_parse_rmc(&(libgnss_gnsstmp->frame_rmc), line)) {
  99. if (libgnss_gnsstmp->frame_rmc.valid) {
  100. memcpy(&(libgnss_gnss->frame_rmc), &libgnss_gnsstmp->frame_rmc, sizeof(struct minmea_sentence_rmc));
  101. #ifdef LUAT_USE_MCU
  102. if (libgnss_gnss->rtc_auto && ((uint32_t)(ticks - libgnss_gnss->fix_at_ticks)) > 600*1000) {
  103. LLOGI("Auto-Set RTC by GNSS RMC");
  104. tblock.tm_sec = libgnss_gnss->frame_rmc.time.seconds;
  105. tblock.tm_min = libgnss_gnss->frame_rmc.time.minutes;
  106. tblock.tm_hour = libgnss_gnss->frame_rmc.time.hours;
  107. tblock.tm_mday = libgnss_gnss->frame_rmc.date.day;
  108. tblock.tm_mon = libgnss_gnss->frame_rmc.date.month;
  109. tblock.tm_year = libgnss_gnss->frame_rmc.date.year;
  110. luat_rtc_set(&tblock);
  111. }
  112. if (libgnss_gnss->fix_at_ticks == 0) {
  113. LLOGI("Fixed"); // TODO 发布系统消息
  114. }
  115. libgnss_gnss->fix_at_ticks = luat_mcu_ticks();
  116. #endif
  117. }
  118. else {
  119. if (libgnss_gnss->fix_at_ticks && libgnss_gnss->frame_rmc.valid) {
  120. LLOGI("Lose"); // TODO 发布系统消息
  121. }
  122. libgnss_gnss->fix_at_ticks = 0;
  123. libgnss_gnss->frame_rmc.valid = 0;
  124. if (libgnss_gnsstmp->frame_rmc.date.year > 0) {
  125. memcpy(&(libgnss_gnss->frame_rmc.date), &(libgnss_gnsstmp->frame_rmc.date), sizeof(struct minmea_date));
  126. }
  127. if (libgnss_gnsstmp->frame_rmc.time.hours > 0) {
  128. memcpy(&(libgnss_gnss->frame_rmc.time), &(libgnss_gnsstmp->frame_rmc.time), sizeof(struct minmea_time));
  129. }
  130. }
  131. //memcpy(&(gnss->frame_rmc), &frame_rmc, sizeof(struct minmea_sentence_rmc));
  132. //LLOGD("RMC %s", line);
  133. //LLOGD("RMC isFix(%d) Lat(%ld) Lng(%ld)", gnss->frame_rmc.valid, gnss->frame_rmc.latitude.value, gnss->frame_rmc.longitude.value);
  134. // if (prev_gnss_fixed != gnss->frame_rmc.valid) {
  135. // lua_getglobal(L, "sys_pub");
  136. // if (lua_isfunction(L, -1)) {
  137. // lua_pushliteral(L, "GPS_STATE");
  138. // lua_pushstring(L, gnss->frame_rmc.valid ? "LOCATION_SUCCESS" : "LOCATION_FAIL");
  139. // lua_call(L, 2, 0);
  140. // }
  141. // else {
  142. // lua_pop(L, 1);
  143. // }
  144. // prev_gnss_fixed = gnss->frame_rmc.valid;
  145. // }
  146. }
  147. } break;
  148. case MINMEA_SENTENCE_GGA: {
  149. //struct minmea_sentence_gga frame_gga;
  150. if (minmea_parse_gga(&libgnss_gnsstmp->frame_gga, line)) {
  151. memcpy(&(libgnss_gnss->frame_gga), &libgnss_gnsstmp->frame_gga, sizeof(struct minmea_sentence_gga));
  152. //LLOGD("$GGA: fix quality: %d", frame_gga.fix_quality);
  153. }
  154. } break;
  155. case MINMEA_SENTENCE_GSA: {
  156. if (minmea_parse_gsa(&(libgnss_gnss->frame_gsa), line)) {
  157. }
  158. } break;
  159. case MINMEA_SENTENCE_GLL: {
  160. if (minmea_parse_gll(&(libgnss_gnss->frame_gll), line)) {
  161. // memcpy(&(gnss->frame_gll), &frame_gll, sizeof(struct minmea_sentence_gsa));
  162. }
  163. } break;
  164. // case MINMEA_SENTENCE_GST: {
  165. // if (minmea_parse_gst(&gnsstmp->frame_gst, line)) {
  166. // memcpy(&(gnss->frame_gst), &gnsstmp->frame_gst, sizeof(struct minmea_sentence_gst));
  167. // }
  168. // } break;
  169. case MINMEA_SENTENCE_GSV: {
  170. //LLOGD("Got GSV : %s", line);
  171. if (minmea_parse_gsv(&frame_gsv, line)) {
  172. //LLOGD("$GSV: message %d of %d", frame_gsv.msg_nr, frame_gsv.total_msgs);
  173. if (frame_gsv.msg_nr == 1) {
  174. //LLOGD("Clean GSV");
  175. memset(&(libgnss_gnss->frame_gsv), 0, sizeof(struct minmea_sentence_gsv) * 3);
  176. }
  177. if (frame_gsv.msg_nr >= 1 && frame_gsv.msg_nr <= 3) {
  178. //LLOGD("memcpy GSV %d", frame_gsv.msg_nr);
  179. memcpy(&(libgnss_gnss->frame_gsv[frame_gsv.msg_nr - 1]), &frame_gsv, sizeof(struct minmea_sentence_gsv));
  180. }
  181. // LLOGD("$GSV: message %d of %d", frame_gsv.msg_nr, frame_gsv.total_msgs);
  182. // LLOGD("$GSV: sattelites in view: %d", frame_gsv.total_sats);
  183. // for (int i = 0; i < 4; i++)
  184. // LLOGD("$GSV: sat nr %d, elevation: %d, azimuth: %d, snr: %d dbm",
  185. // frame_gsv.sats[i].nr,
  186. // frame_gsv.sats[i].elevation,
  187. // frame_gsv.sats[i].azimuth,
  188. // frame_gsv.sats[i].snr);
  189. }
  190. else {
  191. //LLOGD("bad GSV %s", line);
  192. }
  193. } break;
  194. case MINMEA_SENTENCE_VTG: {
  195. //struct minmea_sentence_vtg frame_vtg;
  196. if (minmea_parse_vtg(&(libgnss_gnsstmp->frame_vtg), line)) {
  197. memcpy(&(libgnss_gnss->frame_vtg), &libgnss_gnsstmp->frame_vtg, sizeof(struct minmea_sentence_vtg));
  198. //--------------------------------------
  199. // 暂时不发GPS_MSG_REPORT
  200. // lua_getglobal(L, "sys_pub");
  201. // if (lua_isfunction(L, -1)) {
  202. // lua_pushstring(L, "GPS_MSG_REPORT");
  203. // lua_call(L, 1, 0);
  204. // }
  205. // else {
  206. // lua_pop(L, 1);
  207. // }
  208. //--------------------------------------
  209. }
  210. } break;
  211. case MINMEA_SENTENCE_ZDA: {
  212. if (minmea_parse_zda(&(libgnss_gnsstmp->frame_zda), line)) {
  213. memcpy(&(libgnss_gnss->frame_zda), &libgnss_gnsstmp->frame_zda, sizeof(struct minmea_sentence_zda));
  214. }
  215. } break;
  216. default:
  217. //LLOGD("why happen");
  218. break;
  219. }
  220. return 0;
  221. }