gps_service.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (c) 2022 Actions Semi Co., Inc.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief gps service interface
  9. */
  10. #include <mem_manager.h>
  11. #include <app_manager.h>
  12. #include <srv_manager.h>
  13. #include <msg_manager.h>
  14. #include <sys_manager.h>
  15. #include <thread_timer.h>
  16. #include <gps_manager.h>
  17. #include <device.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <gps/gps.h>
  21. #include <minmea.h>
  22. #define CONFIG_GPS_DEV_NAME "gps"
  23. #define CONFIG_SENSORSRV_STACKSIZE 2048
  24. #define CONFIG_GPSSVR_PRIORITY 6
  25. static gps_res_cb_t gps_res_cb = {NULL};
  26. extern gps_res_t gps_res;
  27. void gps_event_report_nmea(uint8_t *gps_nmea_data)
  28. {
  29. struct app_msg msg = {0};
  30. msg.type = MSG_SENSOR_EVENT;
  31. msg.cmd = MSG_GPS_NMEA_DATA;
  32. msg.ptr = gps_nmea_data;
  33. send_async_msg(GPS_SERVICE_NAME, &msg);
  34. }
  35. static void gps_notify_callback(struct device *dev, struct gps_value *val)
  36. {
  37. gps_event_report_nmea(val->gps_nmea_data);
  38. }
  39. static void _gps_service_init(void)
  40. {
  41. const struct device *gps_dev = device_get_binding("gps");
  42. if (!gps_dev)
  43. {
  44. SYS_LOG_ERR("cannot found key dev gps\n");
  45. }
  46. memset(&gps_res, 0, sizeof(gps_res));
  47. gps_dev_register_notify(gps_dev, gps_notify_callback);
  48. SYS_LOG_INF("_gps_service_init\n");
  49. }
  50. static void gps_enable(void)
  51. {
  52. const struct device *gps_dev = device_get_binding(CONFIG_GPS_DEV_NAME);
  53. if (!gps_dev)
  54. {
  55. SYS_LOG_ERR("cannot found key dev gps\n");
  56. }
  57. gps_dev_enable(gps_dev);
  58. SYS_LOG_INF("gps_dev_enable\n");
  59. }
  60. static void gps_disable(void)
  61. {
  62. const struct device *gps_dev = device_get_binding(CONFIG_GPS_DEV_NAME);
  63. if (!gps_dev)
  64. {
  65. SYS_LOG_ERR("cannot found key dev gps\n");
  66. }
  67. gps_dev_disable(gps_dev);
  68. SYS_LOG_INF("gps_dev_disable\n");
  69. }
  70. static void gps_minmea_parse(const char *sentence)
  71. {
  72. uint8_t parse_state = false;
  73. SYS_LOG_INF("gps sentence: %s\n", sentence);
  74. switch (minmea_sentence_id(sentence, false))
  75. {
  76. #ifdef CONFIG_GPS_PARSE_RMC_ENABLE
  77. case MINMEA_SENTENCE_RMC:
  78. {
  79. struct minmea_sentence_rmc frame;
  80. if (minmea_parse_rmc(&frame, sentence))
  81. {
  82. parse_state = true;
  83. memcpy(&gps_res.rmc_data, &frame, sizeof(frame));
  84. SYS_LOG_INF("$xxRMC sentence parse ok\n");
  85. }
  86. else
  87. {
  88. SYS_LOG_INF("$xxRMC sentence is not parsed\n");
  89. }
  90. }
  91. break;
  92. #endif
  93. #ifdef CONFIG_GPS_PARSE_GGA_ENABLE
  94. case MINMEA_SENTENCE_GGA:
  95. {
  96. struct minmea_sentence_gga frame;
  97. if (minmea_parse_gga(&frame, sentence))
  98. {
  99. parse_state = true;
  100. memcpy(&gps_res.gga_data, &frame, sizeof(frame));
  101. // printk( "$xxGGA: hours: %d\n", frame.time.hours);
  102. // printk( "$xxGGA: minutes: %d\n", frame.time.minutes);
  103. // printk( "$xxGGA: seconds: %d\n", frame.time.seconds);
  104. // printk( "$xxGGA: microseconds: %d\n", frame.time.microseconds);
  105. // printk( "$xxGGA: latitude: %f\n", minmea_tofloat(&frame.latitude));
  106. // printk( "$xxGGA: longitude: %f\n", minmea_tofloat(&frame.longitude));
  107. // printk( "$xxGGA: hdop: %f\n", minmea_tofloat(&frame.hdop));
  108. // printk( "$xxGGA: altitude: %f\n", minmea_tofloat(&frame.altitude));
  109. // printk( "$xxGGA: height: %f\n", minmea_tofloat(&frame.height));
  110. // printk( "$xxGGA: dgps_age: %f\n", minmea_tofloat(&frame.dgps_age));
  111. SYS_LOG_INF("$xxGGA sentence parse ok\n");
  112. }
  113. else
  114. {
  115. SYS_LOG_INF("$xxGGA sentence is not parsed\n");
  116. }
  117. }
  118. break;
  119. #endif
  120. #ifdef CONFIG_GPS_PARSE_GST_ENABLE
  121. case MINMEA_SENTENCE_GST:
  122. {
  123. struct minmea_sentence_gst frame;
  124. if (minmea_parse_gst(&frame, sentence))
  125. {
  126. parse_state = true;
  127. memcpy(&gps_res.gst_data, &frame, sizeof(frame));
  128. SYS_LOG_INF("$xxGST sentence parse ok\n");
  129. }
  130. else
  131. {
  132. SYS_LOG_INF("$xxGST sentence is not parsed\n");
  133. }
  134. }
  135. break;
  136. #endif
  137. #ifdef CONFIG_GPS_PARSE_GSV_ENABLE
  138. case MINMEA_SENTENCE_GSV:
  139. {
  140. struct minmea_sentence_gsv frame;
  141. if (minmea_parse_gsv(&frame, sentence))
  142. {
  143. parse_state = true;
  144. memcpy(&gps_res.gsv_data, &frame, sizeof(frame));
  145. SYS_LOG_INF("$xxGSV sentence parse ok\n");
  146. }
  147. else
  148. {
  149. SYS_LOG_INF("$xxGSV sentence is not parsed\n");
  150. }
  151. }
  152. break;
  153. #endif
  154. #ifdef CONFIG_GPS_PARSE_VTG_ENABLE
  155. case MINMEA_SENTENCE_VTG:
  156. {
  157. struct minmea_sentence_vtg frame;
  158. if (minmea_parse_vtg(&frame, sentence))
  159. {
  160. parse_state = true;
  161. memcpy(&gps_res.vtg_data, &frame, sizeof(frame));
  162. SYS_LOG_INF("$xxVTG sentence parse ok");
  163. }
  164. else
  165. {
  166. SYS_LOG_INF("$xxVTG sentence is not parsed\n");
  167. }
  168. }
  169. break;
  170. #endif
  171. #ifdef CONFIG_GPS_PARSE_ZDA_ENABLE
  172. case MINMEA_SENTENCE_ZDA:
  173. {
  174. struct minmea_sentence_zda frame;
  175. if (minmea_parse_zda(&frame, sentence))
  176. {
  177. parse_state = true;
  178. emcpy(&gps_res.zda_data, &frame, sizeof(frame));
  179. SYS_LOG_INF("$xxZDA sentence parse ok\n");
  180. }
  181. else
  182. {
  183. SYS_LOG_INF("$xxZDA sentence is not parsed\n");
  184. }
  185. }
  186. break;
  187. #endif
  188. case MINMEA_INVALID:
  189. {
  190. SYS_LOG_INF("$xxxxx sentence is not valid\n");
  191. }
  192. break;
  193. default:
  194. {
  195. SYS_LOG_INF("$xxxxx sentence is not parsed\n");
  196. }
  197. break;
  198. }
  199. if ((parse_state == true) && (gps_res_cb != NULL))
  200. {
  201. gps_res_cb(0, &gps_res);
  202. }
  203. }
  204. static void _gps_service_proc(struct app_msg *msg)
  205. {
  206. switch (msg->cmd)
  207. {
  208. case MSG_GPS_ENABLE:
  209. gps_enable();
  210. break;
  211. case MSG_GPS_DISABLE:
  212. gps_disable();
  213. break;
  214. case MSG_GPS_NMEA_DATA:
  215. gps_minmea_parse(msg->ptr);
  216. break;
  217. case MSG_GPS_ADD_CB:
  218. gps_res_cb = (gps_res_cb_t)msg->ptr;
  219. break;
  220. case MSG_GPS_REMOVE_CB:
  221. gps_res_cb = NULL;
  222. break;
  223. default:
  224. break;
  225. }
  226. }
  227. static void _gps_service_main_loop(void *parama1, void *parama2, void *parama3)
  228. {
  229. struct app_msg msg = {0};
  230. bool terminaltion = false;
  231. bool suspended = false;
  232. int timeout;
  233. int result = 0;
  234. printk("gps_service enter\n");
  235. while (!terminaltion)
  236. {
  237. timeout = suspended ? OS_FOREVER : thread_timer_next_timeout();
  238. if (receive_msg(&msg, timeout))
  239. {
  240. // SYS_LOG_INF("gps_service msg:%d, cmd:%d\n", msg.type, msg.cmd);
  241. switch (msg.type)
  242. {
  243. case MSG_INIT_APP:
  244. _gps_service_init();
  245. break;
  246. // case MSG_EXIT_APP:
  247. // _sensor_service_exit();
  248. // terminaltion = true;
  249. // break;
  250. case MSG_SENSOR_EVENT:
  251. _gps_service_proc(&msg);
  252. break;
  253. // case MSG_SUSPEND_APP:
  254. // SYS_LOG_INF("SUSPEND_APP");
  255. // sensor_sleep_suspend();
  256. // suspended = true;
  257. // break;
  258. // case MSG_RESUME_APP:
  259. // SYS_LOG_INF("RESUME_APP");
  260. // sensor_sleep_resume();
  261. // suspended = false;
  262. // break;
  263. default:
  264. break;
  265. }
  266. if (msg.callback)
  267. {
  268. msg.callback(&msg, result, NULL);
  269. }
  270. }
  271. thread_timer_handle_expired();
  272. }
  273. }
  274. char __aligned(ARCH_STACK_PTR_ALIGN) gpssrv_stack_area[CONFIG_SENSORSRV_STACKSIZE];
  275. SERVICE_DEFINE(gps_service,
  276. gpssrv_stack_area, sizeof(gpssrv_stack_area),
  277. CONFIG_GPSSVR_PRIORITY, BACKGROUND_APP,
  278. NULL, NULL, NULL,
  279. _gps_service_main_loop);