blob: c3088bb985fca8ee9dc378c4d96eadbd0d58c713 [file] [log] [blame]
yq.wangd8ded5e2024-08-16 03:27:49 -07001/*
2* gnss_asr5311.c
3*
4* ASR 5311 gnss support source.
5*
6*/
7/******************************************************************************
8
9 EDIT HISTORY FOR FILE
10
11 WHEN WHO WHAT,WHERE,WHY
12-------- -------- -------------------------------------------------------
132024/6/19 LiuBin Initial version
14
15******************************************************************************/
16#include <stdio.h>
17#include <stdlib.h>
18#include <unistd.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <pthread.h>
22#include <time.h>
23#include <signal.h>
24#include <sys/time.h>
25
26#include "mbtk_log.h"
27#include "mbtk_type.h"
28#include "mbtk_gpio.h"
29#include "mbtk_utils.h"
30#include "gnss_utils.h"
31#include "gnss_asr5311.h"
32
33#define UART_BITRATE_NMEA_DEF_FW 115200 // Default bitrate.
34#define GNSS_SET_TIMEOUT 3000 // 3s
35#define GNSS_FW_DOWNLOAD_TIMER_VALUE 6
36#define GNSS_PLATFORM_CTRL_PATH "/sys/devices/platform/asr-gps/ctrl"
37#define GNSS_PLATFORM_STATUS_PATH "/sys/devices/platform/asr-gps/status"
38
39static char config_msg_pm5[] = "PMTEST,5";
40static char config_msg_pm4[] = "PMTEST,4";
41static char config_msg_boot[] = "START,1";
42
43static pthread_cond_t read_cond;
44static pthread_mutex_t read_mutex;
45static bool setting_waitting = FALSE;
46static bool setting_busy = FALSE;
47static void *gnss_set_rsp_ptr = NULL;
48static gnss_err_enum gnss_set_result = GNSS_ERR_OK;
49static timer_t gnss_fw_download_timer_id;
50static int gnss_fw_download_timeout_state = 0;
51static int gnss_fw_download_timer_init_state = 0;
52
53int gnss_write(int fd, const void *data, int data_len);
54
55static void gnss_fw_download_state(__attribute__( (unused)) union sigval sv)
56{
57 LOGD("aboot fw_download timeout");
58 gnss_fw_download_timeout_state = 1;
59 //log2file("%s: gnss fw download timeout\n", __func__);
60
61 system("killall aboot-tiny");
62}
63
64static int gnss_fw_download_timer_init(void)
65{
66 int rc = 0;
67 struct sigevent sigev;
68
69 memset (&sigev, 0, sizeof (struct sigevent));
70 sigev.sigev_value.sival_ptr = &gnss_fw_download_timer_id;
71 sigev.sigev_notify = SIGEV_THREAD;
72 sigev.sigev_notify_attributes = NULL;
73 sigev.sigev_notify_function = gnss_fw_download_state;
74 rc = timer_create(CLOCK_REALTIME, &sigev, &gnss_fw_download_timer_id);
75 if(rc == 0)
76 {
77 gnss_fw_download_timer_init_state = 1;
78 }
79 LOGD("fw_download timer init %d", rc);
80 return rc;
81}
82
83static int gnss_fw_download_timer_start(void)
84{
85 int rc = 0;
86 if(gnss_fw_download_timer_init_state != 1)
87 {
88 rc = gnss_fw_download_timer_init();
89 if(rc != 0)
90 {
91 LOGD("gnss_fw_download_timer_init timer retry fail");
92 return -1;
93 }
94 }
95
96 struct itimerspec ts;
97
98 memset (&ts, 0x00, sizeof (struct itimerspec));
99 ts.it_value.tv_sec = GNSS_FW_DOWNLOAD_TIMER_VALUE;
100 ts.it_value.tv_nsec = 0;
101 ts.it_interval.tv_sec = 0;
102 ts.it_interval.tv_nsec = 0;
103 rc = timer_settime(gnss_fw_download_timer_id, 0, &ts, NULL);
104 gnss_fw_download_timeout_state = 0;
105 LOGD("fw_download timer start %d", rc);
106 return rc;
107}
108
109static int gnss_fw_download_timer_stop(void)
110{
111 if(gnss_fw_download_timer_init_state != 1)
112 {
113 LOGD("gps_fw_download_timer_stop timer not creat");
114 return -1;
115 }
116 int rc = 0;
117 struct itimerspec ts;
118
119 memset (&ts, 0x00, sizeof (struct itimerspec));
120 ts.it_value.tv_sec = 0;
121 ts.it_value.tv_nsec = 0;
122 ts.it_interval.tv_sec = 0;
123 ts.it_interval.tv_nsec = 0;
124 rc = timer_settime(gnss_fw_download_timer_id, 0, &ts, NULL);
125 LOGD("fw_download timer stop %d", rc);
126 return rc;
127}
128
129static int gnss_send_cmd(int fd, const char *cmd, int cmd_len)
130{
131 unsigned char check_sum = 0;
132 unsigned int index;
133 int len = 0;
134 char cmd_buff[64] = {0};
135
136 for(index = 0; index < strlen( (char *)cmd); index++)
137 check_sum ^= cmd[index];
138
139 sprintf((char *)cmd_buff, "$%s*%02x\r\n", cmd, check_sum);
140 len = strlen((char *)cmd_buff)+1;
141 return gnss_write(fd, cmd_buff, len);
142}
143
144static void gnss_set_timer_cb(int signo)
145{
146 if(setting_busy) {
147 pthread_mutex_lock(&read_mutex);
148 pthread_cond_signal(&read_cond);
149 pthread_mutex_unlock(&read_mutex);
150 if(setting_waitting)
151 {
152 setting_waitting = FALSE;
153 }
154 gnss_set_result = GNSS_ERR_TIMEOUT;
155 }
156 return;
157}
158
159static void gnss_hal_gpioctrl(char* str)
160{
161 int fd;
162 fd = open(GNSS_PLATFORM_CTRL_PATH, O_WRONLY);
163
164 if (fd >= 0) {
165 write(fd, str, strlen(str));
166 close(fd);
167 }
168}
169
170static int gnss_module_wait_fw_download_done()
171{
172 int fd;
173 char buf[64];
174 int len;
175 int ret = -1;
176
177 fd = open(GNSS_PLATFORM_STATUS_PATH, O_RDONLY);
178 if (fd >= 0) {
179 sleep(1);
180 len = read(fd, buf, 64);
181 LOGD("FW DONE %s, %d", buf, len);
182 if(!memcmp(buf, "status: on", 10)) {
183 /* FW Downloading is OK. */
184 ret = 0;
185 }
186
187 close(fd);
188 }
189
190 if(!ret)
191 gnss_hal_gpioctrl("off");
192
193 return ret;
194}
195
196static void gnss_cmd_rsp_process(const void *data, int data_len)
197{
198 const char *ptr = (const char*)data;
199 bool flag = FALSE;
200 LOGD("Setting RSP : %s", ptr);
201 if(memcmp(ptr, "$ACKOK", 6) == 0)
202 {
203 flag = TRUE;
204 }
205 else if(memcmp(ptr, "$ACKFAIL", 8) == 0)
206 {
207 //$ACKFAIL,1*56
208 int code = *(ptr + 9) - '0';
209 if(code == 1)
210 {
211 gnss_set_result = GNSS_ERR_FORMAT;
212 }
213 else if(code == 2)
214 {
215 gnss_set_result = GNSS_ERR_CHECKSUM;
216 }
217 else if(code == 3)
218 {
219 gnss_set_result = GNSS_ERR_ARG;
220 }
221 else
222 {
223 gnss_set_result = GNSS_ERR_UNKNOWN;
224 }
225 flag = TRUE;
226 }
227 else
228 {
229 //gnss_set_result = GNSS_ERR_UNKNOWN;
230 }
231
232 if(setting_waitting && flag)
233 {
234 setting_waitting = FALSE;
235 mbtk_timer_clear();
b.liu99c645d2024-06-20 10:52:15 +0800236 pthread_mutex_lock(&read_mutex);
237 pthread_cond_signal(&read_cond);
yq.wangd8ded5e2024-08-16 03:27:49 -0700238 pthread_mutex_unlock(&read_mutex);
239 }
240}
241
242
243int gnss_5311_dev_open()
244{
245 return 0;
246}
247
248int gnss_5311_dev_close(int fd)
249{
250 gnss_send_cmd(fd, config_msg_pm5, strlen(config_msg_pm5));
251 return 0;
252}
253
254int gnss_5311_open(const char *dev)
255{
256 pthread_mutex_init(&read_mutex, NULL);
257 pthread_cond_init(&read_cond, NULL);
258 return gnss_port_open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY, UART_BITRATE_NMEA_DEF_FW, TRUE);
259}
260
261int gnss_5311_close(int fd)
262{
263 pthread_mutex_destroy(&read_mutex);
264 pthread_cond_destroy(&read_cond);
265
266 return gnss_port_close(fd);
267}
268
269int gnss_5311_fw_dl(int fd, const char *fw_name, const char *dev)
270{
271 char cmd[256] = {0};
272 if(memcmp(dev, "/dev/", 5) == 0) {
273 snprintf(cmd, sizeof(cmd), "nice -n -10 aboot-tiny -B 2000000 -s %s -F /etc/jacana_fw.bin -P /etc/jacana_pvt.bin", dev + 5);
274 } else {
275 snprintf(cmd, sizeof(cmd), "nice -n -10 aboot-tiny -B 2000000 -s %s -F /etc/jacana_fw.bin -P /etc/jacana_pvt.bin", dev);
276 }
277
278 int num = 1;
279 LOGD("aboot-tiny start");
280retry_download:
281 gnss_fw_download_timer_start();
282 system(cmd);
283 gnss_fw_download_timer_stop();
284 if(gnss_fw_download_timeout_state == 1)
285 {
286 if(num < 3)
287 {
288 sleep(1);
289 num++;
290 goto retry_download;
291 }
292 else
293 {
294 gnss_fw_download_timeout_state = 0;
295 LOGD("aboot-tiny timeout");
296 LOGD("aboot-tiny stop");
297 return -1;
298 }
299 }
300 else
301 {
302 int ret = gnss_module_wait_fw_download_done();
303 if(ret < 0)
304 {
305 if(num < 3)
306 {
307 num++;
308 goto retry_download;
309 }
310 else
311 {
312 LOGD("aboot-tiny 3 download fail");
313 LOGD("aboot-tiny stop");
314 return -1;
315 }
316 }
317 }
318
319 LOGD("aboot-tiny stop");
320
321 return 0;
322}
323
324void gnss_5311_set_cb(const void *data, int data_len)
325{
326 const char *buff = (const char*)data;
327 if(setting_busy) { // Has setting cmd process.
328 gnss_cmd_rsp_process(data, data_len);
329 }
330}
331
332gnss_err_enum gnss_5311_set(int fd, const char *cmd, void *cmd_rsp, int cmd_rsp_len)
333{
334 if(setting_busy) {
335 return GNSS_ERR_SET_BUSY;
336 } else {
337 bool should_wait_rsp = TRUE;
338 setting_busy = TRUE;
339 gnss_set_rsp_ptr = cmd_rsp;
340 gnss_set_result = GNSS_ERR_OK;
341 char send_cmd[128] = {0};
342 int send_cmd_len = 0;
343
344 mbtk_timer_set(gnss_set_timer_cb, GNSS_SET_TIMEOUT);
345
346 if(memcmp(cmd, "$RESET", 6) == 0) // $RESET,<mode>
347 {
348 gnss_reset_type_enum mode = (gnss_reset_type_enum)atoi(cmd + 7);
349 if(mode == GNSS_RESET_TYPE_HOT || mode == GNSS_RESET_TYPE_WARM || mode == GNSS_RESET_TYPE_COLD) {
350 memset(send_cmd, 0x0, 128);
351 snprintf(send_cmd, 128, "RESET,%d", mode);
352 send_cmd_len = strlen(send_cmd);
353 LOGD("cmd: %s", send_cmd);
354 gnss_send_cmd(fd, send_cmd, send_cmd_len);
355 } else {
356 gnss_set_result = GNSS_ERR_ARG;
357 goto set_fail;
358 }
359 should_wait_rsp = TRUE;
360 }
361 else if(memcmp(cmd, "$NAVISYSCFG", 11) == 0) //$NAVISYSCFG,0x1,2
362 {
363 uint32 navisys = 0,navirate = 0;
364 int ret_num = sscanf(cmd, "$NAVISYSCFG,%d,%d", &navisys, &navirate);
365 if(ret_num < 1 || navisys == 0)
366 {
367 gnss_set_result = GNSS_ERR_ARG;
368 goto set_fail;
369 }
370
371 uint32 new_mode = 0;
372 if(ret_num >= 1)
373 {
374 if(((GNSS_SET_SYSCFG_GPS | GNSS_SET_SYSCFG_BDS | GNSS_SET_SYSCFG_GLO) & navisys) != navisys) {
375 gnss_set_result = GNSS_ERR_ARG;
376 goto set_fail;
377 }
378
379 if(navisys & GNSS_SET_SYSCFG_GPS) { // GPS
380 new_mode |= 0x00000001;
381 }
382 if(navisys & GNSS_SET_SYSCFG_BDS) { // BDS
383 new_mode |= 0x00000002;
384 }
385 if(navisys & GNSS_SET_SYSCFG_GLO) { // GLO
386 new_mode |= 0x00000004;
387 }
388 }
389
390 if(ret_num == 2)
391 {
392 if((GNSS_SET_FREQCFG_1 != navirate) && (GNSS_SET_FREQCFG_2 != navirate) && (GNSS_SET_FREQCFG_5 != navirate) && (GNSS_SET_FREQCFG_10 != navirate))
393 {
394 gnss_set_result = GNSS_ERR_ARG;
395 goto set_fail;
396 }
397 }
398
399 memset(send_cmd, 0x0, 128);
400 if(ret_num == 1)
401 {
402 snprintf(send_cmd, 128, "NAVISYSCFG,0x%X", new_mode);
403 }
404 else
405 {
406 snprintf(send_cmd, 128, "NAVISYSCFG,0x%X,%d", new_mode, navirate);
407 }
408 send_cmd_len = strlen(send_cmd);
409 LOGD("cmd: %s", send_cmd);
410 gnss_send_cmd(fd, send_cmd, send_cmd_len);
411 should_wait_rsp = TRUE;
412 }
413 else if(memcmp(cmd, "$MSGCFG", 7) == 0) //$MSGCFG,<mode>,<rate>
414 {
415 uint32 mode;
416 uint32 msgmask = 0;
417 int rate;
418 if(2 == sscanf(cmd, "$MSGCFG,%d,%d", &mode, &rate)) {
419 int time = rate / 1000; // s
420 if(time < 0) {
421 gnss_set_result = GNSS_ERR_ARG;
422 goto set_fail;
423 }
424
425 if(((GNSS_SET_MSGCFG_RMC | GNSS_SET_MSGCFG_VTG | GNSS_SET_MSGCFG_GGA | GNSS_SET_MSGCFG_GSA
426 | GNSS_SET_MSGCFG_GST | GNSS_SET_MSGCFG_GSV | GNSS_SET_MSGCFG_GLL | GNSS_SET_MSGCFG_ZDA
427 | GNSS_SET_MSGCFG_DHV | GNSS_SET_MSGCFG_TXT | GNSS_SET_MSGCFG_DTM) & mode) != mode) {
428 gnss_set_result = GNSS_ERR_ARG;
429 goto set_fail;
430 }
431
432 if(mode & GNSS_SET_MSGCFG_RMC)
433 {
434 msgmask |= 0x00000001;
435 }
436 if(mode & GNSS_SET_MSGCFG_VTG)
437 {
438 msgmask |= 0x00000002;
439 }
440 if(mode & GNSS_SET_MSGCFG_GGA)
441 {
442 msgmask |= 0x00000004;
443 }
444 if(mode & GNSS_SET_MSGCFG_GSA)
445 {
446 msgmask |= 0x00000008;
447 }
448 if(mode & GNSS_SET_MSGCFG_GSV)
449 {
450 msgmask |= 0x00000010;
451 }
452 if(mode & GNSS_SET_MSGCFG_GLL)
453 {
454 msgmask |= 0x00000020;
455 }
456 if(mode & GNSS_SET_MSGCFG_ZDA)
457 {
458 msgmask |= 0x00000040;
459 }
460 if(mode & GNSS_SET_MSGCFG_GST)
461 {
462 msgmask |= 0x00000080;
463 }
464 if(mode & GNSS_SET_MSGCFG_TXT)
465 {
466 msgmask |= 0x00000100;
467 }
468 if(mode & GNSS_SET_MSGCFG_DHV)
469 {
470 msgmask |= 0x00000200;
471 }
472 if(mode & GNSS_SET_MSGCFG_DTM)
473 {
474 msgmask |= 0x00000400;
475 }
476 memset(send_cmd, 0x0, 128);
477 snprintf(send_cmd, 128, "MSGCFG,0,0x%X,%d", msgmask, time);
478 send_cmd_len = strlen(send_cmd);
479 LOGD("cmd: %s", send_cmd);
480 gnss_send_cmd(fd, send_cmd, send_cmd_len);
481 }
482 else
483 {
484 gnss_set_result = GNSS_ERR_ARG;
485 goto set_fail;
486 }
487
488 should_wait_rsp = TRUE;
489 }
490 else if(memcmp(cmd, "$MINEL", 6) == 0) //$MINEL,<elev>
491 {
492 uint32 elev = 0;
493 elev = (uint32)atoi(cmd + 7);
494 if(elev != GNSS_SET_EVEL_5 && elev != GNSS_SET_EVEL_15)
495 {
496 gnss_set_result = GNSS_ERR_ARG;
497 goto set_fail;
498 }
499
500 memset(send_cmd, 0x0, 128);
501 snprintf(send_cmd, 128, "MINEL,%d", elev);
502 send_cmd_len = strlen(send_cmd);
503 LOGD("cmd: %s", send_cmd);
504 gnss_send_cmd(fd, send_cmd, send_cmd_len);
505 should_wait_rsp = TRUE;
506 }
507 else if(memcmp(cmd, "$NMEACFG", 8) == 0) // $NMEACFG,<ver>
508 {
509 uint32 mode,ver = 0;
510 mode = (uint32)atoi(cmd + 9);
511 if(mode == GNSS_SET_NMEAVER_4_00)
512 {
513 ver = 0x40;
514 }
515 else if(mode == GNSS_SET_NMEAVER_4_10)
516 {
517 ver = 0x41;
518 }
519 else
520 {
521 gnss_set_result = GNSS_ERR_ARG;
522 goto set_fail;
523 }
524
525 memset(send_cmd, 0x0, 128);
526 snprintf(send_cmd, 128, "NMEACFG,0x%X", ver);
527 send_cmd_len = strlen(send_cmd);
528 LOGD("cmd: %s", send_cmd);
529 gnss_send_cmd(fd, send_cmd, send_cmd_len);
530 should_wait_rsp = TRUE;
531 }
532 else
533 {
534 LOGW("Unknown cmd:%s", cmd);
535 gnss_set_result = GNSS_ERR_UNSUPPORT;
536 goto set_fail;
537 }
538
539set_success:
540 if(should_wait_rsp) {
541 setting_waitting = TRUE;
542 pthread_mutex_lock(&read_mutex);
543 pthread_cond_wait(&read_cond, &read_mutex);
544 pthread_mutex_unlock(&read_mutex);
545 } else {
546 mbtk_timer_clear();
547 }
548
549 setting_busy = FALSE;
550 return gnss_set_result;
551set_fail:
552 setting_busy = FALSE;
553 mbtk_timer_clear();
554 return gnss_set_result;
555 }
556}
557