comparison Small_CPU/Src/uart.c @ 704:f1b40364b0af

Added protocol functions for UART DiveO2 sensor: The code has been modified to support the handling of several protocols (including baud rate changes). The data is requested by polling and passed via DMA into a ringbuffer which is then parsed by a cyclic function call in the main loop. At the moment only the O2 values are forwarded but because the sensor send several types of data within a signle message already more is extracted but yet discarded.
author Ideenmodellierer
date Fri, 28 Oct 2022 20:49:21 +0200
parents fca2bd25e6e2
children 045ff7800501
comparison
equal deleted inserted replaced
703:2f457024049b 704:f1b40364b0af
20 */ 20 */
21 /* Includes ------------------------------------------------------------------*/ 21 /* Includes ------------------------------------------------------------------*/
22 #include "uart.h" 22 #include "uart.h"
23 #include "externalInterface.h" 23 #include "externalInterface.h"
24 #include "data_exchange.h" 24 #include "data_exchange.h"
25 #include <string.h> /* memset */
25 26
26 /* Private variables ---------------------------------------------------------*/ 27 /* Private variables ---------------------------------------------------------*/
27 28
28 #define CHUNK_SIZE (20u) /* the DMA will handle chunk size transfers */ 29 #define CHUNK_SIZE (20u) /* the DMA will handle chunk size transfers */
29 #define CHUNKS_PER_BUFFER (3u) 30 #define CHUNKS_PER_BUFFER (3u)
35 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ 36 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */
36 static uint8_t rxReadIndex; /* Index at which new data is stared */ 37 static uint8_t rxReadIndex; /* Index at which new data is stared */
37 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ 38 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */
38 static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */ 39 static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */
39 40
41 char tmpRxBuf[30];
42 uint8_t tmpRxIdx = 0;
43
44 static uartO2Status_t Comstatus_O2 = UART_O2_INIT;
45
46 static uint32_t DigitalO2ID = 0;
47
40 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ 48 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */
41 float LED_ZeroOffset = 0.0; 49 float LED_ZeroOffset = 0.0;
42 float pCO2 = 0.0; 50 float pCO2 = 0.0;
43 /* Exported functions --------------------------------------------------------*/ 51 /* Exported functions --------------------------------------------------------*/
44 52
45 void MX_USART1_UART_Init(void) 53 void MX_USART1_UART_Init(void)
46 { 54 {
47 /* regular init */ 55 /* regular init */
48 56
49 huart1.Instance = USART1; 57 huart1.Instance = USART1;
50 huart1.Init.BaudRate = 9600; 58
59 if(externalInterface_GetUARTProtocol() == 0x04)
60 {
61 huart1.Init.BaudRate = 19200;
62 Comstatus_O2 = UART_O2_INIT;
63 }
64 else
65 {
66 huart1.Init.BaudRate = 9600;
67 }
51 huart1.Init.WordLength = UART_WORDLENGTH_8B; 68 huart1.Init.WordLength = UART_WORDLENGTH_8B;
52 huart1.Init.StopBits = UART_STOPBITS_1; 69 huart1.Init.StopBits = UART_STOPBITS_1;
53 huart1.Init.Parity = UART_PARITY_NONE; 70 huart1.Init.Parity = UART_PARITY_NONE;
54 huart1.Init.Mode = UART_MODE_TX_RX; 71 huart1.Init.Mode = UART_MODE_TX_RX;
55 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; 72 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
56 huart1.Init.OverSampling = UART_OVERSAMPLING_16; 73 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
57 74
58 HAL_UART_Init(&huart1); 75 HAL_UART_Init(&huart1);
59 76
77 MX_USART1_DMA_Init();
78
60 rxReadIndex = 0; 79 rxReadIndex = 0;
61 lastCmdIndex = 0; 80 lastCmdIndex = 0;
62 rxWriteIndex = 0; 81 rxWriteIndex = 0;
63 dmaActive = 0; 82 dmaActive = 0;
83 Comstatus_O2 = UART_O2_INIT;
64 } 84 }
65 85
66 void MX_USART1_UART_DeInit(void) 86 void MX_USART1_UART_DeInit(void)
67 { 87 {
88 HAL_DMA_Abort(&hdma_usart1_rx);
68 HAL_DMA_DeInit(&hdma_usart1_rx); 89 HAL_DMA_DeInit(&hdma_usart1_rx);
69 HAL_UART_DeInit(&huart1); 90 HAL_UART_DeInit(&huart1);
70 } 91 }
71 92
72 void MX_USART1_DMA_Init() 93 void MX_USART1_DMA_Init()
354 } 375 }
355 } 376 }
356 } 377 }
357 #endif 378 #endif
358 379
380 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
381 {
382 switch (O2State)
383 {
384 case UART_O2_CHECK: *cmdLength = snprintf((char*)cmdString, 10, "#LOGO");
385 break;
386 case UART_O2_REQ_INFO: *cmdLength = snprintf((char*)cmdString, 10, "#VERS");
387 break;
388 case UART_O2_REQ_ID: *cmdLength = snprintf((char*)cmdString, 10, "#IDNR");
389 break;
390 case UART_O2_REQ_O2: *cmdLength = snprintf((char*)cmdString, 10, "#DOXY");
391 break;
392
393 default: *cmdLength = 0;
394 break;
395 }
396 if(*cmdLength != 0)
397 {
398 cmdString[*cmdLength] = 0x0D;
399 *cmdLength = *cmdLength + 1;
400 }
401 }
402
403 void StringToInt(char *pstr, uint32_t *pInt)
404 {
405 uint8_t index = 0;
406 uint32_t result = 0;
407 while((pstr[index] >= '0') && (pstr[index] <= '9'))
408 {
409 result *=10;
410 result += pstr[index] - '0';
411 index++;
412 }
413 *pInt = result;
414 }
415
416 void HandleUARTDigitalO2(void)
417 {
418 static uint32_t lastO2ReqTick = 0;
419
420 static uartO2RxState_t rxState = O2RX_IDLE;
421 static uint32_t lastReceiveTick = 0;
422 static uint8_t lastAlive = 0;
423 static uint8_t curAlive = 0;
424
425 static uint8_t cmdLength = 0;
426 static uint8_t cmdString[10];
427 static uint8_t cmdReadIndex = 0;
428
429 uint32_t tmpO2 = 0;
430 uint32_t tmpData = 0;
431 uint8_t localRX = rxReadIndex;
432 uint32_t tick = HAL_GetTick();
433
434
435 if(Comstatus_O2 == UART_O2_INIT)
436 {
437 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
438 lastAlive = 0;
439 curAlive = 0;
440
441 Comstatus_O2 = UART_O2_CHECK;
442 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
443 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
444
445 rxState = O2RX_CONFIRM;
446 cmdReadIndex = 0;
447 lastO2ReqTick = tick;
448
449 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
450 {
451 dmaActive = 1;
452 }
453 }
454 if(time_elapsed_ms(lastO2ReqTick,tick) > 1000) /* repeat request once per second */
455 {
456 lastO2ReqTick = tick;
457 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */
458 {
459 Comstatus_O2 = UART_O2_REQ_O2;
460 rxState = O2RX_CONFIRM;
461 }
462 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
463
464 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
465 }
466
467 while((rxBuffer[localRX]!=0))
468 {
469
470 lastReceiveTick = tick;
471 switch(rxState)
472 {
473 case O2RX_CONFIRM: if(rxBuffer[localRX] == '#')
474 {
475 cmdReadIndex = 0;
476 }
477 if(rxBuffer[localRX] == cmdString[cmdReadIndex])
478 {
479 cmdReadIndex++;
480 if(cmdReadIndex == cmdLength - 1)
481 {
482 tmpRxIdx = 0;
483 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
484 switch (Comstatus_O2)
485 {
486 case UART_O2_CHECK: Comstatus_O2 = UART_O2_REQ_INFO;
487 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
488 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
489 break;
490 case UART_O2_REQ_ID: rxState = O2RX_GETNR;
491 break;
492 case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE;
493 break;
494 case UART_O2_REQ_O2: rxState = O2RX_GETO2;
495 break;
496 default: Comstatus_O2 = UART_O2_IDLE;
497 rxState = O2RX_IDLE;
498 break;
499 }
500 }
501 }
502 break;
503
504 case O2RX_GETSTATUS:
505 case O2RX_GETTEMP:
506 case O2RX_GETTYPE:
507 case O2RX_GETVERSION:
508 case O2RX_GETCHANNEL:
509 case O2RX_GETSUBSENSORS:
510 case O2RX_GETO2:
511 case O2RX_GETNR: if(rxBuffer[localRX] != 0x0D)
512 {
513 if(rxBuffer[localRX] != ' ')
514 {
515 tmpRxBuf[tmpRxIdx++] = rxBuffer[localRX];
516 }
517 else
518 {
519 if(tmpRxIdx != 0)
520 {
521 switch(rxState)
522 {
523 case O2RX_GETCHANNEL: StringToInt(tmpRxBuf,&tmpData);
524 rxState = O2RX_GETVERSION;
525 break;
526 case O2RX_GETVERSION: StringToInt(tmpRxBuf,&tmpData);
527 rxState = O2RX_GETSUBSENSORS;
528 break;
529 case O2RX_GETTYPE: StringToInt(tmpRxBuf,&tmpData);
530 rxState = O2RX_GETCHANNEL;
531 break;
532
533 case O2RX_GETO2: StringToInt(tmpRxBuf,&tmpO2);
534 setExternalInterfaceChannel(0,(float)(tmpO2 / 10000.0));
535 rxState = O2RX_GETTEMP;
536 break;
537 case O2RX_GETTEMP: rxState = O2RX_GETSTATUS;
538 break;
539 default:
540 break;
541 }
542 memset((char*) tmpRxBuf, 0, tmpRxIdx);
543 tmpRxIdx = 0;
544 }
545 }
546 }
547 else
548 {
549 switch (rxState)
550 {
551 case O2RX_GETSTATUS: StringToInt(tmpRxBuf,&tmpData);
552 Comstatus_O2 = UART_O2_IDLE;
553 rxState = O2RX_IDLE;
554 break;
555 case O2RX_GETSUBSENSORS: StringToInt(tmpRxBuf,&tmpData);
556 Comstatus_O2 = UART_O2_IDLE;
557 rxState = O2RX_IDLE;
558 break;
559 case O2RX_GETNR: StringToInt((char*)rxBuffer,&DigitalO2ID);
560 /* no break */
561 default: Comstatus_O2 = UART_O2_IDLE;
562 rxState = O2RX_IDLE;
563 break;
564 }
565 }
566 break;
567 default: rxState = O2RX_IDLE;
568 break;
569
570 }
571
572 localRX++;
573 rxReadIndex++;
574 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
575 {
576 localRX = 0;
577 rxReadIndex = 0;
578 }
579 }
580
581 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */
582 {
583 if(curAlive == lastAlive)
584 {
585 setExternalInterfaceChannel(0,0.0);
586 setExternalInterfaceChannel(1,0.0);
587 setExternalInterfaceChannel(2,0.0);
588 }
589 lastAlive = curAlive;
590 }
591
592 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */
593 {
594 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
595 {
596 dmaActive = 1;
597 }
598 }
599 }
600
601
359 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 602 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
360 { 603 {
361 if(huart == &huart1) 604 if(huart == &huart1)
362 { 605 {
363 dmaActive = 0; 606 dmaActive = 0;
368 } 611 }
369 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */ 612 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */
370 { 613 {
371 if(externalInterface_isEnabledPower33()) 614 if(externalInterface_isEnabledPower33())
372 { 615 {
616 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
373 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) 617 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
374 { 618 {
375 dmaActive = 1; 619 dmaActive = 1;
376 } 620 }
377 } 621 }