comparison Small_CPU/Src/uart_Internal.c @ 932:effadaa3a1f7 Evo_2_23

Cleanup Gnss UART implementation: The first draft of the internal UART implementation was just a copy of the external UART handling. To avoid duplicated code and maintainance issue both UARTs (external/internal 6/1) share the same functions. To enable this a control structure has to be used as function input which defines the none shared resources like DMA control and rx/tx buffers
author Ideenmodellierer
date Sat, 07 Dec 2024 21:28:08 +0100
parents 5a9bc2e6112d
children f41974734268
comparison
equal deleted inserted replaced
931:5a9bc2e6112d 932:effadaa3a1f7
26 #include "externalInterface.h" 26 #include "externalInterface.h"
27 #include "data_exchange.h" 27 #include "data_exchange.h"
28 #include <string.h> /* memset */ 28 #include <string.h> /* memset */
29 29
30 30
31 static uint8_t isEndIndication6(uint8_t index);
32 static uartGnssStatus_t gnssState = UART_GNSS_INIT;
33 static gnssRequest_s activeRequest = {0,0};
34
35 /* Private variables ---------------------------------------------------------*/ 31 /* Private variables ---------------------------------------------------------*/
36
37
38 #define TX_BUF_SIZE (40u) /* max length for commands */
39 #define CHUNK_SIZE (50u) /* the DMA will handle chunk size transfers */
40 #define CHUNKS_PER_BUFFER (3u)
41 32
42 #define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor (UART mux) */ 33 #define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor (UART mux) */
43 #define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */ 34 #define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */
44 #define TIMEOUT_SENSOR_ANSWER (300) /* Time till a request is repeated if no answer was received */ 35 #define TIMEOUT_SENSOR_ANSWER (300) /* Time till a request is repeated if no answer was received */
45 36
46
47 static receiveStateGnss_t rxState = GNSSRX_READY;
48 static uint8_t GnssConnected = 0; /* Binary indicator if a sensor is connected or not */
49
50 static uint8_t writeIndex = 0;
51
52 static uint16_t dataToRead = 0;
53
54 DMA_HandleTypeDef hdma_usart6_rx, hdma_usart6_tx; 37 DMA_HandleTypeDef hdma_usart6_rx, hdma_usart6_tx;
55 38
56 uint8_t tx6Buffer[CHUNK_SIZE]; /* tx uses less bytes */ 39 uint8_t tx6Buffer[CHUNK_SIZE]; /* tx uses less bytes */
57 uint8_t tx6BufferQue[TX_BUF_SIZE]; /* In MUX mode command may be send shortly after each other => allow q 1 entry que */
58 uint8_t tx6BufferQueLen;
59 40
60 uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ 41 uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */
61 uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ 42 uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */
62 43
63 static uint8_t rx6WriteIndex; /* Index of the data item which is analysed */ 44 sUartComCtrl Uart6Ctrl;
64 static uint8_t rx6ReadIndex; /* Index at which new data is stared */
65
66 static uint8_t dmaRx6Active; /* Indicator if DMA reception needs to be started */
67 static uint8_t dmaTx6Active; /* Indicator if DMA reception needs to be started */
68
69 45
70 /* Exported functions --------------------------------------------------------*/ 46 /* Exported functions --------------------------------------------------------*/
71
72 void UART_clearRx6Buffer(void)
73 {
74 uint16_t index = 0;
75 do
76 {
77 rxBufferUart6[index++] = BUFFER_NODATA_LOW;
78 rxBufferUart6[index++] = BUFFER_NODATA_HIGH;
79 } while (index < sizeof(rxBufferUart6));
80
81 rx6ReadIndex = 0;
82 rx6WriteIndex = 0;
83 }
84 47
85 void GNSS_IO_init() { 48 void GNSS_IO_init() {
86 49
87 GPIO_InitTypeDef GPIO_InitStruct = { 0 }; 50 GPIO_InitTypeDef GPIO_InitStruct = { 0 };
88 /* Peripheral clock enable */ 51 /* Peripheral clock enable */
174 huart6.Init.Mode = UART_MODE_TX_RX; 137 huart6.Init.Mode = UART_MODE_TX_RX;
175 huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; 138 huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
176 huart6.Init.OverSampling = UART_OVERSAMPLING_16; 139 huart6.Init.OverSampling = UART_OVERSAMPLING_16;
177 HAL_UART_Init(&huart6); 140 HAL_UART_Init(&huart6);
178 141
179 UART_clearRx6Buffer(); 142 UART_clearRxBuffer(&Uart6Ctrl);
180 dmaRx6Active = 0; 143
181 dmaTx6Active = 0; 144 Uart6Ctrl.pHandle = &huart6;
182 tx6BufferQueLen = 0; 145 Uart6Ctrl.dmaRxActive = 0;
183 } 146 Uart6Ctrl.dmaTxActive = 0;
184 147 Uart6Ctrl.pRxBuffer = rxBufferUart6;
185 148 Uart6Ctrl.pTxBuffer = txBufferUart6;
186 149 Uart6Ctrl.rxReadIndex = 0;
187 void UART6_SendCmdUbx(const uint8_t *cmd, uint8_t len) 150 Uart6Ctrl.rxWriteIndex = 0;
188 { 151 Uart6Ctrl.txBufferQueLen = 0;
189 if(len < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */ 152
190 { 153 UART_SetGnssCtrl(&Uart6Ctrl);
191 if(dmaRx6Active == 0) 154 }
192 {
193 UART6_StartDMA_Receiption();
194 }
195 memcpy(tx6Buffer, cmd, len);
196 if(HAL_OK == HAL_UART_Transmit_DMA(&huart6,tx6Buffer,len))
197 {
198 dmaTx6Active = 1;
199 }
200 }
201 }
202
203 uint8_t isEndIndication6(uint8_t index)
204 {
205 uint8_t ret = 0;
206 if(index % 2)
207 {
208 if(rxBufferUart6[index] == BUFFER_NODATA_HIGH)
209 {
210 ret = 1;
211 }
212 }
213 else
214 {
215 if(rxBufferUart6[index] == BUFFER_NODATA_LOW)
216 {
217 ret = 1;
218 }
219 }
220
221 return ret;
222 }
223
224 void UART6_StartDMA_Receiption()
225 {
226 if(dmaRx6Active == 0)
227 {
228 if(((rx6WriteIndex / CHUNK_SIZE) != (rx6ReadIndex / CHUNK_SIZE)) || ((isEndIndication6(rx6WriteIndex)) && (isEndIndication6(rx6WriteIndex + 1)))) /* start next transfer if we did not catch up with read index */
229 {
230 if(HAL_OK == HAL_UART_Receive_DMA (&huart6, &rxBufferUart6[rx6WriteIndex], CHUNK_SIZE))
231 {
232 dmaRx6Active = 1;
233 }
234 }
235 }
236 }
237
238
239
240 void UART6_RxCpltCallback(UART_HandleTypeDef *huart)
241 {
242 if(huart == &huart6)
243 {
244 dmaRx6Active = 0;
245 rx6WriteIndex+=CHUNK_SIZE;
246 if(rx6WriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
247 {
248 rx6WriteIndex = 0;
249 }
250 UART6_StartDMA_Receiption();
251 }
252 }
253 void UART6_TxCpltCallback(UART_HandleTypeDef *huart)
254 {
255 if(huart == &huart6)
256 {
257 dmaTx6Active = 0;
258 UART6_WriteData();
259 if(tx6BufferQueLen)
260 {
261 memcpy(tx6Buffer, tx6BufferQue, tx6BufferQueLen);
262 HAL_UART_Transmit_DMA(&huart6,tx6Buffer,tx6BufferQueLen);
263 dmaTx6Active = 1;
264 tx6BufferQueLen = 0;
265 }
266 }
267 }
268
269 void UART6_ReadData()
270 {
271 uint8_t localRX = rx6ReadIndex;
272 uint8_t futureIndex = rx6ReadIndex + 1;
273 uint8_t moreData = 0;
274
275 if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
276 {
277 futureIndex = 0;
278 }
279
280 if(!isEndIndication6(futureIndex))
281 {
282 moreData = 1;
283 }
284
285 if((!isEndIndication6(localRX)) || (moreData))
286 do
287 {
288 while((!isEndIndication6(localRX)) || (moreData))
289 {
290 moreData = 0;
291 UART6_Gnss_ProcessData(rxBufferUart6[localRX]);
292
293 if(localRX % 2)
294 {
295 rxBufferUart6[localRX] = BUFFER_NODATA_HIGH;
296 }
297 else
298 {
299 rxBufferUart6[localRX] = BUFFER_NODATA_LOW;
300 }
301
302 localRX++;
303 rx6ReadIndex++;
304 if(rx6ReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
305 {
306 localRX = 0;
307 rx6ReadIndex = 0;
308 }
309 futureIndex++;
310 if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
311 {
312 futureIndex = 0;
313 }
314 }
315 if(!isEndIndication6(futureIndex))
316 {
317 moreData = 1;
318 }
319 } while(moreData);
320 }
321
322 void UART6_WriteData(void)
323 {
324 if(huart6.hdmatx->State == HAL_DMA_STATE_READY)
325 {
326 huart6.gState = HAL_UART_STATE_READY;
327 dmaTx6Active = 0;
328 }
329 if(huart6.hdmarx->State == HAL_DMA_STATE_READY)
330 {
331 huart6.RxState = HAL_UART_STATE_READY;
332 dmaRx6Active = 0;
333 }
334 }
335
336 void UART6_Gnss_SendCmd(uint8_t GnssCmd)
337 {
338 const uint8_t* pData;
339 uint8_t txLength = 0;
340
341 switch (GnssCmd)
342 {
343 case GNSSCMD_LOADCONF_0: pData = configUBX;
344 txLength = sizeof(configUBX) / sizeof(uint8_t);
345 break;
346 case GNSSCMD_LOADCONF_1: pData = setNMEA410;
347 txLength = sizeof(setNMEA410) / sizeof(uint8_t);
348 break;
349 case GNSSCMD_LOADCONF_2: pData = setGNSS;
350 txLength = sizeof(setGNSS) / sizeof(uint8_t);
351 break;
352 case GNSSCMD_GET_PVT_DATA: pData = getPVTData;
353 txLength = sizeof(getPVTData) / sizeof(uint8_t);
354 break;
355 case GNSSCMD_GET_NAV_DATA: pData = getNavigatorData;
356 txLength = sizeof(getNavigatorData) / sizeof(uint8_t);
357 break;
358 case GNSSCMD_GET_NAVSAT_DATA: pData = getNavSat;
359 txLength = sizeof(getNavSat) / sizeof(uint8_t);
360 break;
361 default:
362 break;
363 }
364 if(txLength != 0)
365 {
366 activeRequest.class = pData[2];
367 activeRequest.id = pData[3];
368 UART6_SendCmdUbx(pData, txLength);
369 }
370 }
371
372 void UART6_Gnss_Control(void)
373 {
374 static uint32_t warmupTick = 0;
375 static uint8_t dataToggle = 0;
376
377 switch (gnssState)
378 {
379 case UART_GNSS_INIT: gnssState = UART_GNSS_WARMUP;
380 warmupTick = HAL_GetTick();
381 UART_clearRxBuffer();
382 break;
383 case UART_GNSS_WARMUP: if(time_elapsed_ms(warmupTick,HAL_GetTick()) > 1000)
384 {
385 gnssState = UART_GNSS_LOADCONF_0;
386 }
387 break;
388 case UART_GNSS_LOADCONF_0: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_0);
389 gnssState = UART_GNSS_LOADCONF_1;
390 rxState = GNSSRX_DETECT_ACK_0;
391 break;
392 case UART_GNSS_LOADCONF_1: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_1);
393 gnssState = UART_GNSS_LOADCONF_2;
394 rxState = GNSSRX_DETECT_ACK_0;
395 break;
396 case UART_GNSS_LOADCONF_2: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_2);
397 gnssState = UART_GNSS_IDLE;
398 rxState = GNSSRX_DETECT_ACK_0;
399 break;
400 case UART_GNSS_IDLE: if(dataToggle)
401 {
402 UART6_Gnss_SendCmd(GNSSCMD_GET_PVT_DATA);
403 gnssState = UART_GNSS_GET_PVT;
404 rxState = GNSSRX_DETECT_HEADER_0;
405 dataToggle = 0;
406 }
407 else
408 {
409 UART6_Gnss_SendCmd(GNSSCMD_GET_NAVSAT_DATA);
410 gnssState = UART_GNSS_GET_SAT;
411 rxState = GNSSRX_DETECT_HEADER_0;
412 dataToggle = 1;
413 }
414 break;
415 default:
416 break;
417 }
418 }
419
420 void UART6_Gnss_ProcessData(uint8_t data)
421 {
422 static uint16_t rxLength = 0;
423 static uint8_t ck_A = 0;
424 static uint8_t ck_B = 0;
425 static uint8_t ck_A_Ref = 0;
426 static uint8_t ck_B_Ref = 0;
427
428 GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
429 if((rxState >= GNSSRX_DETECT_HEADER_2) && (rxState < GNSSRX_READ_CK_A))
430 {
431 ck_A += data;
432 ck_B += ck_A;
433 }
434
435 switch(rxState)
436 {
437 case GNSSRX_DETECT_ACK_0:
438 case GNSSRX_DETECT_HEADER_0: if(data == 0xB5)
439 {
440 writeIndex = 0;
441 memset(GNSS_Handle.uartWorkingBuffer,0xff, sizeof(GNSS_Handle.uartWorkingBuffer));
442 GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
443 rxState++;
444 ck_A = 0;
445 ck_B = 0;
446 }
447 break;
448 case GNSSRX_DETECT_ACK_1:
449 case GNSSRX_DETECT_HEADER_1: if(data == 0x62)
450 {
451 rxState++;
452 }
453 else
454 {
455 rxState = GNSSRX_DETECT_HEADER_0;
456 }
457 break;
458 case GNSSRX_DETECT_ACK_2: if(data == 0x05)
459 {
460 rxState++;
461 }
462 else
463 {
464 rxState = GNSSRX_DETECT_HEADER_0;
465 }
466 break;
467 case GNSSRX_DETECT_ACK_3: if((data == 0x01) || (data == 0x00))
468 {
469 GnssConnected = 1;
470 rxState = GNSSRX_READY;
471 }
472 else
473 {
474 rxState = GNSSRX_DETECT_HEADER_0;
475 }
476 break;
477 case GNSSRX_DETECT_HEADER_2: if(data == activeRequest.class)
478 {
479 rxState++;
480 }
481 else
482 {
483 rxState = GNSSRX_DETECT_HEADER_0;
484 }
485 break;
486 case GNSSRX_DETECT_HEADER_3: if(data == activeRequest.id)
487 {
488 rxState = GNSSRX_DETECT_LENGTH_0;
489 }
490 else
491 {
492 rxState = GNSSRX_DETECT_HEADER_0;
493 }
494 break;
495 case GNSSRX_DETECT_LENGTH_0: rxLength = GNSS_Handle.uartWorkingBuffer[4];
496 rxState = GNSSRX_DETECT_LENGTH_1;
497 break;
498 case GNSSRX_DETECT_LENGTH_1: rxLength += (GNSS_Handle.uartWorkingBuffer[5] << 8);
499 rxState = GNSSRX_READ_DATA;
500 dataToRead = rxLength;
501 break;
502 case GNSSRX_READ_DATA: if(dataToRead > 0)
503 {
504 dataToRead--;
505 }
506 if(dataToRead == 0)
507 {
508 rxState = GNSSRX_READ_CK_A;
509 }
510 break;
511 case GNSSRX_READ_CK_A: ck_A_Ref = data;
512 rxState++;
513 break;
514 case GNSSRX_READ_CK_B: ck_B_Ref = data;
515 if((ck_A_Ref == ck_A) && (ck_B_Ref == ck_B))
516 {
517 switch(gnssState)
518 {
519 case UART_GNSS_GET_PVT:GNSS_ParsePVTData(&GNSS_Handle);
520 break;
521 case UART_GNSS_GET_SAT: GNSS_ParseNavSatData(&GNSS_Handle);
522 break;
523 default:
524 break;
525 }
526 }
527 rxState = GNSSRX_DETECT_HEADER_0;
528 gnssState = UART_GNSS_IDLE;
529 break;
530
531 default: rxState = GNSSRX_READY;
532 break;
533 }
534 }
535
536 155
537 void UART6_HandleUART() 156 void UART6_HandleUART()
538 { 157 {
539 static uint8_t retryRequest = 0; 158 static uint8_t retryRequest = 0;
540 static uint32_t lastRequestTick = 0; 159 static uint32_t lastRequestTick = 0;
541 static uint32_t TriggerTick = 0; 160 static uint32_t TriggerTick = 0;
542 static uint8_t timeToTrigger = 0; 161 static uint8_t timeToTrigger = 0;
543 uint32_t tick = HAL_GetTick(); 162 uint32_t tick = HAL_GetTick();
544 163
164 uartGnssStatus_t gnssState = uartGnss_GetState();
165
545 if(gnssState != UART_GNSS_INIT) 166 if(gnssState != UART_GNSS_INIT)
546 { 167 {
547 UART6_ReadData(); 168 UART_ReadData(SENSOR_GNSS);
548 UART6_WriteData(); 169 UART_WriteData(&Uart6Ctrl);
549 } 170 }
550 if(gnssState == UART_GNSS_INIT) 171 if(gnssState == UART_GNSS_INIT)
551 { 172 {
552 lastRequestTick = tick; 173 lastRequestTick = tick;
553 TriggerTick = tick - 10; /* just to make sure control is triggered */ 174 TriggerTick = tick - 10; /* just to make sure control is triggered */
574 timeToTrigger = 1; 195 timeToTrigger = 1;
575 196
576 if((gnssState == UART_GNSS_GET_SAT) || (gnssState == UART_GNSS_GET_PVT)) /* timeout */ 197 if((gnssState == UART_GNSS_GET_SAT) || (gnssState == UART_GNSS_GET_PVT)) /* timeout */
577 { 198 {
578 gnssState = UART_GNSS_IDLE; 199 gnssState = UART_GNSS_IDLE;
200 uartGnss_SetState(gnssState);
579 } 201 }
580 timeToTrigger = 1; 202 timeToTrigger = 1;
581 } 203 }
582 if((timeToTrigger != 0) && (time_elapsed_ms(TriggerTick,tick) > timeToTrigger)) 204 if((timeToTrigger != 0) && (time_elapsed_ms(TriggerTick,tick) > timeToTrigger))
583 { 205 {
584 timeToTrigger = 0; 206 timeToTrigger = 0;
585 UART6_Gnss_Control(); 207 uartGnss_Control();
586 } 208 }
587 209
588 } 210 }
589 211
590 212