Mercurial > public > ostc4
annotate Small_CPU/Src/GNSS.c @ 931:5a9bc2e6112d Evo_2_23 tip
Added Sat Status Overview:
In addition to the navigation data now information regarding the satelliete and signal status are visualized. To enable the a new command has been added to the communication protocol and the position view has been extended.
author | Ideenmodellierer |
---|---|
date | Tue, 03 Dec 2024 20:32:51 +0100 |
parents | c0553dd70608 |
children |
rev | line source |
---|---|
887 | 1 /* |
2 * GNSS.c | |
3 * | |
4 * Created on: 03.10.2020 | |
5 * Author: SimpleMethod | |
6 * | |
7 *Copyright 2020 SimpleMethod | |
8 * | |
9 *Permission is hereby granted, free of charge, to any person obtaining a copy of | |
10 *this software and associated documentation files (the "Software"), to deal in | |
11 *the Software without restriction, including without limitation the rights to | |
12 *use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | |
13 *of the Software, and to permit persons to whom the Software is furnished to do | |
14 *so, subject to the following conditions: | |
15 * | |
16 *The above copyright notice and this permission notice shall be included in all | |
17 *copies or substantial portions of the Software. | |
18 * | |
19 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
22 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
23 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
25 *THE SOFTWARE. | |
26 ****************************************************************************** | |
27 */ | |
28 | |
931 | 29 #include <string.h> |
887 | 30 #include "GNSS.h" |
31 | |
32 union u_Short uShort; | |
33 union i_Short iShort; | |
34 union u_Long uLong; | |
35 union i_Long iLong; | |
36 | |
37 /*! | |
38 * Structure initialization. | |
39 * @param GNSS Pointer to main GNSS structure. | |
40 * @param huart Pointer to uart handle. | |
41 */ | |
42 void GNSS_Init(GNSS_StateHandle *GNSS, UART_HandleTypeDef *huart) { | |
43 GNSS->huart = huart; | |
44 GNSS->year = 0; | |
45 GNSS->month = 0; | |
46 GNSS->day = 0; | |
47 GNSS->hour = 0; | |
48 GNSS->min = 0; | |
49 GNSS->sec = 0; | |
50 GNSS->fixType = 0; | |
51 GNSS->lon = 0; | |
52 GNSS->lat = 0; | |
53 GNSS->height = 0; | |
54 GNSS->hMSL = 0; | |
55 GNSS->hAcc = 0; | |
56 GNSS->vAcc = 0; | |
57 GNSS->gSpeed = 0; | |
58 GNSS->headMot = 0; | |
59 } | |
60 | |
61 /*! | |
62 * Searching for a header in data buffer and matching class and message ID to buffer data. | |
63 * @param GNSS Pointer to main GNSS structure. | |
64 */ | |
899
2225c467f1e9
Added data path and visualization for position data:
Ideenmodellierer
parents:
887
diff
changeset
|
65 uint8_t GNSS_ParseBuffer(GNSS_StateHandle *GNSS) { |
2225c467f1e9
Added data path and visualization for position data:
Ideenmodellierer
parents:
887
diff
changeset
|
66 |
2225c467f1e9
Added data path and visualization for position data:
Ideenmodellierer
parents:
887
diff
changeset
|
67 uint8_t DataReceived = 0; |
887 | 68 |
69 for (int var = 0; var <= 100; ++var) { | |
70 if (GNSS->uartWorkingBuffer[var] == 0xB5 | |
71 && GNSS->uartWorkingBuffer[var + 1] == 0x62) { | |
899
2225c467f1e9
Added data path and visualization for position data:
Ideenmodellierer
parents:
887
diff
changeset
|
72 DataReceived = 1; |
887 | 73 if (GNSS->uartWorkingBuffer[var + 2] == 0x27 |
74 && GNSS->uartWorkingBuffer[var + 3] == 0x03) { //Look at: 32.19.1.1 u-blox 8 Receiver description | |
75 GNSS_ParseUniqID(GNSS); | |
76 } else if (GNSS->uartWorkingBuffer[var + 2] == 0x01 | |
77 && GNSS->uartWorkingBuffer[var + 3] == 0x21) { //Look at: 32.17.14.1 u-blox 8 Receiver description | |
78 GNSS_ParseNavigatorData(GNSS); | |
79 } else if (GNSS->uartWorkingBuffer[var + 2] == 0x01 | |
80 && GNSS->uartWorkingBuffer[var + 3] == 0x07) { //ook at: 32.17.30.1 u-blox 8 Receiver description | |
81 GNSS_ParsePVTData(GNSS); | |
82 } else if (GNSS->uartWorkingBuffer[var + 2] == 0x01 | |
83 && GNSS->uartWorkingBuffer[var + 3] == 0x02) { // Look at: 32.17.15.1 u-blox 8 Receiver description | |
84 GNSS_ParsePOSLLHData(GNSS); | |
85 } | |
86 } | |
87 } | |
899
2225c467f1e9
Added data path and visualization for position data:
Ideenmodellierer
parents:
887
diff
changeset
|
88 return DataReceived; |
887 | 89 } |
90 | |
91 /*! | |
92 * Make request for unique chip ID data. | |
93 * @param GNSS Pointer to main GNSS structure. | |
94 */ | |
95 void GNSS_GetUniqID(GNSS_StateHandle *GNSS) { | |
96 HAL_UART_Transmit_DMA(GNSS->huart, getDeviceID, | |
97 sizeof(getDeviceID) / sizeof(uint8_t)); | |
98 HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 17); | |
99 } | |
100 | |
101 /*! | |
102 * Make request for UTC time solution data. | |
103 * @param GNSS Pointer to main GNSS structure. | |
104 */ | |
105 void GNSS_GetNavigatorData(GNSS_StateHandle *GNSS) { | |
106 HAL_UART_Transmit_DMA(GNSS->huart, getNavigatorData, | |
107 sizeof(getNavigatorData) / sizeof(uint8_t)); | |
108 HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 28); | |
109 } | |
110 | |
111 /*! | |
112 * Make request for geodetic position solution data. | |
113 * @param GNSS Pointer to main GNSS structure. | |
114 */ | |
115 void GNSS_GetPOSLLHData(GNSS_StateHandle *GNSS) { | |
116 HAL_UART_Transmit_DMA(GNSS->huart, getPOSLLHData, | |
117 sizeof(getPOSLLHData) / sizeof(uint8_t)); | |
118 HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 36); | |
119 } | |
120 | |
121 /*! | |
122 * Make request for navigation position velocity time solution data. | |
123 * @param GNSS Pointer to main GNSS structure. | |
124 */ | |
125 void GNSS_GetPVTData(GNSS_StateHandle *GNSS) { | |
126 HAL_UART_Transmit_DMA(GNSS->huart, getPVTData, | |
127 sizeof(getPVTData) / sizeof(uint8_t)); | |
128 HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 100); | |
129 } | |
130 | |
131 /*! | |
132 * Parse data to unique chip ID standard. | |
133 * Look at: 32.19.1.1 u-blox 8 Receiver description | |
134 * @param GNSS Pointer to main GNSS structure. | |
135 */ | |
136 void GNSS_ParseUniqID(GNSS_StateHandle *GNSS) { | |
137 for (int var = 0; var < 5; ++var) { | |
138 GNSS->uniqueID[var] = GNSS_Handle.uartWorkingBuffer[10 + var]; | |
139 } | |
140 } | |
141 | |
142 /*! | |
143 * Changing the GNSS mode. | |
144 * Look at: 32.10.19 u-blox 8 Receiver description | |
145 */ | |
146 void GNSS_SetMode(GNSS_StateHandle *GNSS, short gnssMode) { | |
147 if (gnssMode == 0) { | |
148 HAL_UART_Transmit_DMA(GNSS->huart, setPortableMode,sizeof(setPortableMode) / sizeof(uint8_t)); | |
149 } else if (gnssMode == 1) { | |
150 HAL_UART_Transmit_DMA(GNSS->huart, setStationaryMode,sizeof(setStationaryMode) / sizeof(uint8_t)); | |
151 } else if (gnssMode == 2) { | |
152 HAL_UART_Transmit_DMA(GNSS->huart, setPedestrianMode,sizeof(setPedestrianMode) / sizeof(uint8_t)); | |
153 } else if (gnssMode == 3) { | |
154 HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t)); | |
155 } else if (gnssMode == 4) { | |
156 HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t)); | |
157 } else if (gnssMode == 5) { | |
158 HAL_UART_Transmit_DMA(GNSS->huart, setAirbone1GMode,sizeof(setAirbone1GMode) / sizeof(uint8_t)); | |
159 } else if (gnssMode == 6) { | |
160 HAL_UART_Transmit_DMA(GNSS->huart, setAirbone2GMode,sizeof(setAirbone2GMode) / sizeof(uint8_t)); | |
161 } else if (gnssMode == 7) { | |
162 HAL_UART_Transmit_DMA(GNSS->huart, setAirbone4GMode,sizeof(setAirbone4GMode) / sizeof(uint8_t)); | |
163 } else if (gnssMode == 8) { | |
164 HAL_UART_Transmit_DMA(GNSS->huart, setWirstMode,sizeof(setWirstMode) / sizeof(uint8_t)); | |
165 } else if (gnssMode == 9) { | |
166 HAL_UART_Transmit_DMA(GNSS->huart, setBikeMode,sizeof(setBikeMode) / sizeof(uint8_t)); | |
167 } | |
168 } | |
169 /*! | |
170 * Parse data to navigation position velocity time solution standard. | |
171 * Look at: 32.17.15.1 u-blox 8 Receiver description. | |
172 * @param GNSS Pointer to main GNSS structure. | |
173 */ | |
174 void GNSS_ParsePVTData(GNSS_StateHandle *GNSS) { | |
919 | 175 |
176 static float searchCnt = 1.0; | |
177 | |
887 | 178 uShort.bytes[0] = GNSS_Handle.uartWorkingBuffer[10]; |
179 GNSS->yearBytes[0]=GNSS_Handle.uartWorkingBuffer[10]; | |
180 uShort.bytes[1] = GNSS_Handle.uartWorkingBuffer[11]; | |
181 GNSS->yearBytes[1]=GNSS_Handle.uartWorkingBuffer[11]; | |
182 GNSS->year = uShort.uShort; | |
183 GNSS->month = GNSS_Handle.uartWorkingBuffer[12]; | |
184 GNSS->day = GNSS_Handle.uartWorkingBuffer[13]; | |
185 GNSS->hour = GNSS_Handle.uartWorkingBuffer[14]; | |
186 GNSS->min = GNSS_Handle.uartWorkingBuffer[15]; | |
187 GNSS->sec = GNSS_Handle.uartWorkingBuffer[16]; | |
188 GNSS->fixType = GNSS_Handle.uartWorkingBuffer[26]; | |
189 | |
190 for (int var = 0; var < 4; ++var) { | |
191 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 30]; | |
192 GNSS->lonBytes[var]= GNSS_Handle.uartWorkingBuffer[var + 30]; | |
193 } | |
194 GNSS->lon = iLong.iLong; | |
195 GNSS->fLon=(float)iLong.iLong/10000000.0; | |
196 for (int var = 0; var < 4; ++var) { | |
197 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 34]; | |
198 GNSS->latBytes[var]=GNSS_Handle.uartWorkingBuffer[var + 34]; | |
199 } | |
200 GNSS->lat = iLong.iLong; | |
201 GNSS->fLat=(float)iLong.iLong/10000000.0; | |
202 for (int var = 0; var < 4; ++var) { | |
203 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 38]; | |
204 } | |
205 GNSS->height = iLong.iLong; | |
206 | |
207 for (int var = 0; var < 4; ++var) { | |
208 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 42]; | |
209 GNSS->hMSLBytes[var] = GNSS_Handle.uartWorkingBuffer[var + 42]; | |
210 } | |
211 GNSS->hMSL = iLong.iLong; | |
212 | |
213 for (int var = 0; var < 4; ++var) { | |
214 uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 46]; | |
215 } | |
216 GNSS->hAcc = uLong.uLong; | |
217 | |
218 for (int var = 0; var < 4; ++var) { | |
219 uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 50]; | |
220 } | |
221 GNSS->vAcc = uLong.uLong; | |
222 | |
223 for (int var = 0; var < 4; ++var) { | |
224 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 66]; | |
225 GNSS->gSpeedBytes[var] = GNSS_Handle.uartWorkingBuffer[var + 66]; | |
226 } | |
227 GNSS->gSpeed = iLong.iLong; | |
228 | |
229 for (int var = 0; var < 4; ++var) { | |
230 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 70]; | |
231 } | |
232 GNSS->headMot = iLong.iLong * 1e-5; // todo I'm not sure this good options. | |
919 | 233 |
234 if((GNSS->fLat == 0.0) && (GNSS->fLon == 0.0)) | |
235 { | |
236 GNSS->fLat = searchCnt++; | |
237 } | |
887 | 238 } |
239 | |
240 /*! | |
241 * Parse data to UTC time solution standard. | |
242 * Look at: 32.17.30.1 u-blox 8 Receiver description. | |
243 * @param GNSS Pointer to main GNSS structure. | |
244 */ | |
931 | 245 void GNSS_ParseNavSatData(GNSS_StateHandle *GNSS) { |
246 | |
247 uint8_t loop = 0; | |
248 uint8_t searchIndex = 0; | |
249 uint8_t statIndex = 0; /* only 4 state information will be forwarded */ | |
250 uint8_t signalQuality = 0; | |
251 GNSS->numSat = GNSS_Handle.uartWorkingBuffer[11]; | |
252 | |
253 memset(GNSS->statSat, 0, sizeof(GNSS->statSat)); | |
254 | |
255 if(GNSS->numSat > 0) | |
256 { | |
257 searchIndex = 0; | |
258 while((searchIndex < GNSS->numSat) && (statIndex < 4)) /* get good signal quality */ | |
259 { | |
260 signalQuality = (GNSS_Handle.uartWorkingBuffer[22 + searchIndex * 12] & 0x7); | |
261 if(signalQuality > 4) | |
262 { | |
263 GNSS->statSat[statIndex++] = signalQuality; | |
264 } | |
265 if(statIndex == 4) break; | |
266 searchIndex++; | |
267 } | |
268 searchIndex = 0; | |
269 while((searchIndex < GNSS->numSat) && (statIndex < 4)) /* get medium signal quality */ | |
270 { | |
271 signalQuality = (GNSS_Handle.uartWorkingBuffer[22 + searchIndex * 12] & 0x7); | |
272 if((signalQuality > 2) && (signalQuality <= 4)) | |
273 { | |
274 GNSS->statSat[statIndex++] = signalQuality; | |
275 } | |
276 if(statIndex == 4) break; | |
277 searchIndex++; | |
278 } | |
279 searchIndex = 0; | |
280 while((searchIndex < GNSS->numSat) && (statIndex < 4)) /* get poor signal quality */ | |
281 { | |
282 signalQuality = (GNSS_Handle.uartWorkingBuffer[22 + searchIndex * 12] & 0x7); | |
283 if(signalQuality <= 2) | |
284 { | |
285 GNSS->statSat[statIndex++] = signalQuality; | |
286 } | |
287 if(statIndex == 4) break; | |
288 searchIndex++; | |
289 } | |
290 loop++; | |
291 } | |
292 } | |
293 | |
887 | 294 void GNSS_ParseNavigatorData(GNSS_StateHandle *GNSS) { |
295 uShort.bytes[0] = GNSS_Handle.uartWorkingBuffer[18]; | |
296 uShort.bytes[1] = GNSS_Handle.uartWorkingBuffer[19]; | |
297 GNSS->year = uShort.uShort; | |
298 GNSS->month = GNSS_Handle.uartWorkingBuffer[20]; | |
299 GNSS->day = GNSS_Handle.uartWorkingBuffer[21]; | |
300 GNSS->hour = GNSS_Handle.uartWorkingBuffer[22]; | |
301 GNSS->min = GNSS_Handle.uartWorkingBuffer[23]; | |
302 GNSS->sec = GNSS_Handle.uartWorkingBuffer[24]; | |
303 } | |
304 | |
931 | 305 |
887 | 306 /*! |
307 * Parse data to geodetic position solution standard. | |
308 * Look at: 32.17.14.1 u-blox 8 Receiver description. | |
309 * @param GNSS Pointer to main GNSS structure. | |
310 */ | |
311 void GNSS_ParsePOSLLHData(GNSS_StateHandle *GNSS) { | |
312 for (int var = 0; var < 4; ++var) { | |
313 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 10]; | |
314 } | |
315 GNSS->lon = iLong.iLong; | |
316 GNSS->fLon=(float)iLong.iLong/10000000.0; | |
317 | |
318 for (int var = 0; var < 4; ++var) { | |
319 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 14]; | |
320 } | |
321 GNSS->lat = iLong.iLong; | |
322 GNSS->fLat=(float)iLong.iLong/10000000.0; | |
323 | |
324 for (int var = 0; var < 4; ++var) { | |
325 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 18]; | |
326 } | |
327 GNSS->height = iLong.iLong; | |
328 | |
329 for (int var = 0; var < 4; ++var) { | |
330 iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 22]; | |
331 } | |
332 GNSS->hMSL = iLong.iLong; | |
333 | |
334 for (int var = 0; var < 4; ++var) { | |
335 uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 26]; | |
336 } | |
337 GNSS->hAcc = uLong.uLong; | |
338 | |
339 for (int var = 0; var < 4; ++var) { | |
340 uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 30]; | |
341 } | |
342 GNSS->vAcc = uLong.uLong; | |
343 } | |
344 | |
345 /*! | |
346 * Sends the basic configuration: Activation of the UBX standard, change of NMEA version to 4.10 and turn on of the Galileo system. | |
347 * @param GNSS Pointer to main GNSS structure. | |
348 */ | |
349 void GNSS_LoadConfig(GNSS_StateHandle *GNSS) { | |
350 HAL_UART_Transmit_DMA(GNSS->huart, configUBX, | |
351 sizeof(configUBX) / sizeof(uint8_t)); | |
352 HAL_Delay(250); | |
353 HAL_UART_Transmit_DMA(GNSS->huart, setNMEA410, | |
354 sizeof(setNMEA410) / sizeof(uint8_t)); | |
355 HAL_Delay(250); | |
356 HAL_UART_Transmit_DMA(GNSS->huart, setGNSS, | |
357 sizeof(setGNSS) / sizeof(uint8_t)); | |
358 HAL_Delay(250); | |
359 } | |
360 | |
361 | |
362 | |
363 /*! | |
364 * Creates a checksum based on UBX standard. | |
365 * @param class Class value from UBX doc. | |
366 * @param messageID MessageID value from UBX doc. | |
367 * @param dataLength Data length value from UBX doc. | |
368 * @param payload Just payload. | |
369 * @return Returns checksum. | |
370 */ | |
371 uint8_t GNSS_Checksum(uint8_t class, uint8_t messageID, uint8_t dataLength,uint8_t *payload) { | |
372 //todo: Look at 32.4 UBX Checksum | |
373 return 0; | |
374 } |