blob: 57b2e30ac924fa6dcef05d7676f3e31178d71616 [file] [log] [blame]
b.liuf9fbfa12024-06-14 15:53:59 +08001/*
2* gnss_hd8122.c
3*
4* HD8122 GNSS source.
5*
6*/
7/******************************************************************************
8
9 EDIT HISTORY FOR FILE
10
11 WHEN WHO WHAT,WHERE,WHY
12-------- -------- -------------------------------------------------------
132024/6/14 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
22#include "mbtk_log.h"
23#include "mbtk_type.h"
24#include "mbtk_gpio.h"
25#include "gnss_utils.h"
26#include "gnss_hd8122.h"
27
28#define UART_BITRATE_NMEA_DEF_FW 115200 // Default bitrate.
29#define GNSS_POWER_GPIO 43
b.liu5f950c52024-06-15 20:13:12 +080030#define GNSS_SET_TIMEOUT 3000 // 3s
31#define GNSS_PACK_BUFF_SIZE 1024
32
b.liuf9fbfa12024-06-14 15:53:59 +080033
34static pthread_cond_t read_cond;
35static pthread_mutex_t read_mutex;
b.liu5f950c52024-06-15 20:13:12 +080036static bool setting_busy = FALSE;
37static void *gnss_set_rsp_ptr = NULL;
38static gnss_err_enum gnss_set_result = GNSS_ERR_OK;
b.liuf9fbfa12024-06-14 15:53:59 +080039
b.liu5f950c52024-06-15 20:13:12 +080040int gnss_write(int fd, const void *data, int data_len);
41
42static uint16 fletcher16(const uint8_t* data, int data_len) {
43 uint16_t sum1 = 0;
44 uint16_t sum2 = 0;
45 int index;
46
47 for (index = 0; index < data_len; ++index ) {
48 sum1 = (sum1 + data[index]) % 0xff;
49 sum2 = (sum2 + sum1) % 0xff;
50 }
51
52 // ???
53 sum2--;
54
55 return (sum2 << 8) | sum1;
56}
57
58static void gnss_set_timer_cb(int signo)
59{
60 if(setting_busy) {
61 pthread_mutex_lock(&read_mutex);
62 pthread_cond_signal(&read_cond);
63 pthread_mutex_unlock(&read_mutex);
64 gnss_set_result = GNSS_ERR_TIMEOUT;
65 }
66 return;
67}
68
69
70static int pack_create(hd8122_id_type_enum id_type, uint8 id, uint16 data_len, const uint8 *data, uint8 *pack, int pack_len)
71{
72 if(pack == NULL || pack_len < HD8122_PACK_LEN_MIN) {
73 return -1;
74 }
75 memset(pack, 0, pack_len);
76 uint8 *data_ptr = pack;
77 data_ptr += uint16_2_byte(HD8122_PACK_HEAD, data_ptr, false);
78 *data_ptr++ = (uint8)id_type;
79 *data_ptr++ = id;
80 data_ptr += uint16_2_byte(data_len, data_ptr, false);
81 if(data_len > 0) {
82 memcpy(data_ptr, data, data_len);
83 data_ptr += data_len;
84 }
85 data_ptr += uint16_2_byte(fletcher16(pack + 2, 4 + data_len), data_ptr, false);
86 return (data_ptr - pack);
87}
88
89static void gnss_cmd_rsp_process(const void *data, int data_len) {
90 const char *ptr = (const char*)data;
91 log_hex("RSP", data, data_len);
92 if(0)
93 {
94 mbtk_timer_clear();
95
96 pthread_mutex_lock(&read_mutex);
97 pthread_cond_signal(&read_cond);
98 pthread_mutex_unlock(&read_mutex);
99 }
100}
101
102static gnss_err_enum gnss_8122_reset(int fd, int reset)
103{
104 uint8 buff[GNSS_PACK_BUFF_SIZE];
105 LOGD("RESET");
106 int len = pack_create(HD8122_ID_TYPE_CFG, HD8122_ID_CFG_SIMPLERST, 1, (uint8*)(&reset), buff, sizeof(buff));
107 if(len <= 0) {
108 LOGE("pack_create() fail.");
109 return GNSS_ERR_ARG;
110 }
111 log_hex("PACK", buff, len);
112 gnss_write(fd, buff, len);
113 return GNSS_ERR_OK;
114}
b.liuf9fbfa12024-06-14 15:53:59 +0800115
116int gnss_8122_dev_open()
117{
118 return mbtk_gpio_value_set(GNSS_POWER_GPIO, MBTK_GPIO_DIRECT_OUT, 1);
119}
120
121int gnss_8122_dev_close()
122{
123 return mbtk_gpio_value_set(GNSS_POWER_GPIO, MBTK_GPIO_DIRECT_OUT, 0);
124}
125
126int gnss_8122_open(const char *dev)
127{
128 pthread_mutex_init(&read_mutex, NULL);
129 pthread_cond_init(&read_cond, NULL);
130 return gnss_port_open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY, UART_BITRATE_NMEA_DEF_FW, TRUE);
131}
132
133int gnss_8122_close(int fd)
134{
135 pthread_mutex_destroy(&read_mutex);
136 pthread_cond_destroy(&read_cond);
137 return gnss_port_close(fd);
138}
139
140int gnss_8122_fw_dl()
141{
142 return 0;
143}
144
b.liu5f950c52024-06-15 20:13:12 +0800145void gnss_8122_set_cb(const void *data, int data_len)
146{
147 const char *buff = (const char*)data;
148 if(setting_busy) {
149 gnss_cmd_rsp_process(data, data_len);
150 }
151}
b.liuf9fbfa12024-06-14 15:53:59 +0800152
153gnss_err_enum gnss_8122_set(int fd, const char *cmd, void *cmd_rsp, int cmd_rsp_len)
154{
b.liu5f950c52024-06-15 20:13:12 +0800155 if(setting_busy) {
156 return GNSS_ERR_SET_BUSY;
157 } else {
158 bool should_wait_rsp = TRUE;
159 setting_busy = TRUE;
160 gnss_set_rsp_ptr = cmd_rsp;
161 gnss_set_result = GNSS_ERR_OK;
162 mbtk_timer_set(gnss_set_timer_cb, GNSS_SET_TIMEOUT);
163
164 if(memcmp(cmd, "reset", 5) == 0) {
165 gnss_set_result = gnss_8122_reset(fd, atoi(cmd + 6));
166 if(gnss_set_result != GNSS_ERR_OK) {
167 goto set_fail;
168 }
169 should_wait_rsp = FALSE;
170 }
171 else
172 {
173 LOGW("Unknown cmd:%s", cmd);
174 gnss_set_result = GNSS_ERR_UNSUPPORT;
175 goto set_fail;
176 }
177
178set_success:
179 if(should_wait_rsp) {
180 pthread_mutex_lock(&read_mutex);
181 pthread_cond_wait(&read_cond, &read_mutex);
182 pthread_mutex_unlock(&read_mutex);
183 } else {
184 mbtk_timer_clear();
185 }
186
187 setting_busy = FALSE;
188 return gnss_set_result;
189set_fail:
190 setting_busy = FALSE;
191 mbtk_timer_clear();
192 return gnss_set_result;
193 }
b.liuf9fbfa12024-06-14 15:53:59 +0800194}
195
b.liu5f950c52024-06-15 20:13:12 +0800196