comparison Small_CPU/Src/uart.c @ 787:aeb72882f30a

Dev Bugfx Empty buffer indication and stability improvments: The mux prototype used ASCII coding for channel selection while the current realization used real number (0...4) for addressing the mux. The UART read function uses the '0' to indicate an empty buffer element. The mux now loops back '0' used by channel selection causing the read function to process the data. As result data interrups are visible at the display. To avoid this another character has been defined indicate empty buffer locations. Beside this the functionality has been improved with regard to access speed and better recovery in case of transition failure.
author Ideenmodellierer
date Sun, 04 Jun 2023 21:59:26 +0200
parents 3c0b16473af4
children bb37d4f3e50e
comparison
equal deleted inserted replaced
786:19ab6f3ed52a 787:aeb72882f30a
24 #include "data_exchange.h" 24 #include "data_exchange.h"
25 #include <string.h> /* memset */ 25 #include <string.h> /* memset */
26 26
27 /* Private variables ---------------------------------------------------------*/ 27 /* Private variables ---------------------------------------------------------*/
28 28
29 #define BUFFER_NODATA (7u) /* The read function needs a byte which indecated that no data for processing is available.*/
30 /* This byte shall never appear in a normal data steam */
31
29 #define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ 32 #define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */
30 #define CHUNKS_PER_BUFFER (5u) 33 #define CHUNKS_PER_BUFFER (5u)
31 #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 */
32 #define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor */ 35 #define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor */
33 UART_HandleTypeDef huart1; 36 UART_HandleTypeDef huart1;
81 84
82 HAL_UART_Init(&huart1); 85 HAL_UART_Init(&huart1);
83 86
84 MX_USART1_DMA_Init(); 87 MX_USART1_DMA_Init();
85 88
86 memset(rxBuffer,0,sizeof(rxBuffer)); 89 memset(rxBuffer,BUFFER_NODATA,sizeof(rxBuffer));
87 rxReadIndex = 0; 90 rxReadIndex = 0;
88 lastCmdIndex = 0; 91 lastCmdIndex = 0;
89 rxWriteIndex = 0; 92 rxWriteIndex = 0;
90 dmaActive = 0; 93 dmaActive = 0;
91 digO2Connected = 0; 94 digO2Connected = 0;
513 } 516 }
514 else 517 else
515 { 518 {
516 if(Comstatus_O2 == UART_O2_INIT) 519 if(Comstatus_O2 == UART_O2_INIT)
517 { 520 {
518 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE); 521 memset((char*)&rxBuffer[rxWriteIndex],(int)BUFFER_NODATA, sizeof(rxBuffer));
519 memset((char*) &tmpSensorDataDiveO2, 0, sizeof(tmpSensorDataDiveO2)); 522 memset((char*) &tmpSensorDataDiveO2, 0, sizeof(tmpSensorDataDiveO2));
520 externalInterface_SetSensorData(0,(uint8_t*)&tmpSensorDataDiveO2); 523 externalInterface_SetSensorData(0xFF,(uint8_t*)&tmpSensorDataDiveO2);
521 524
522 lastAlive = 0; 525 lastAlive = 0;
523 curAlive = 0; 526 curAlive = 0;
524 527
525 Comstatus_O2 = UART_O2_CHECK; 528 Comstatus_O2 = UART_O2_CHECK;
529 lastComState = UART_O2_IDLE;
526 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); 530 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
527 DigitalO2_SelectSensor(activeSensor); 531
528 if(activeSensor < MAX_MUX_CHANNEL) 532 if(activeSensor < MAX_MUX_CHANNEL)
529 { 533 {
530 externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2); 534 externalInterface_GetSensorData(activeSensor, (uint8_t*)&tmpSensorDataDiveO2);
531 } 535 }
532 delayStartTick = tick; 536
533 tickToTX = COMMAND_TX_DELAY; 537 tickToTX = COMMAND_TX_DELAY;
534 538
535 rxState = O2RX_CONFIRM; 539 rxState = O2RX_CONFIRM;
536 cmdReadIndex = 0; 540 cmdReadIndex = 0;
537 errorReadIndex = 0; 541 errorReadIndex = 0;
538 respondErrorDetected = 0; 542 respondErrorDetected = 0;
539 digO2Connected = 0; 543 digO2Connected = 0;
540 lastO2ReqTick = tick;
541 switchChannel = 1; 544 switchChannel = 1;
542 545
543 requestIntervall = 0; 546 requestIntervall = 0;
544 for(index = 0; index < MAX_MUX_CHANNEL; index++) 547 for(index = 0; index < MAX_MUX_CHANNEL; index++)
545 { 548 {
555 else 558 else
556 { 559 {
557 requestIntervall = REQUEST_INT_SENSOR_MS; 560 requestIntervall = REQUEST_INT_SENSOR_MS;
558 } 561 }
559 UART_StartDMA_Receiption(); 562 UART_StartDMA_Receiption();
563 lastO2ReqTick = tick + requestIntervall + 1;
560 } 564 }
561 if(time_elapsed_ms(lastO2ReqTick,tick) > requestIntervall) /* repeat request or iterate to next sensor */ 565 if(time_elapsed_ms(lastO2ReqTick,tick) > requestIntervall) /* repeat request or iterate to next sensor */
562 { 566 {
567 respondErrorDetected = 0;
563 lastO2ReqTick = tick; 568 lastO2ReqTick = tick;
564 index = activeSensor; 569 index = activeSensor;
565 if((lastComState == Comstatus_O2) && (Comstatus_O2 != UART_O2_IDLE)) 570 if((lastComState == Comstatus_O2) && (Comstatus_O2 != UART_O2_IDLE))
566 { 571 {
567 if(retryRequest) 572 if(retryRequest)
581 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */ 586 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */
582 { 587 {
583 retryRequest = 1; 588 retryRequest = 1;
584 if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */ 589 if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */
585 { 590 {
586 switchChannel = 0;
587 if(activeSensor < MAX_MUX_CHANNEL) 591 if(activeSensor < MAX_MUX_CHANNEL)
588 { 592 {
589 do 593 do
590 { 594 {
591 index++; 595 index++;
598 activeSensor = index; 602 activeSensor = index;
599 switchChannel = 1; 603 switchChannel = 1;
600 break; 604 break;
601 } 605 }
602 } while(index != activeSensor); 606 } while(index != activeSensor);
607 externalInterface_GetSensorData(activeSensor, (uint8_t*)&tmpSensorDataDiveO2);
603 } 608 }
604 } 609 }
605 Comstatus_O2 = UART_O2_REQ_RAW; 610 if((activeSensor != MAX_MUX_CHANNEL) && (tmpSensorDataDiveO2.sensorId == 0))
606 rxState = O2RX_CONFIRM; 611 {
607 } 612 Comstatus_O2 = UART_O2_REQ_ID;
613 }
614 else
615 {
616 Comstatus_O2 = UART_O2_REQ_RAW;
617 }
618 }
619 rxState = O2RX_CONFIRM;
608 if(switchChannel) 620 if(switchChannel)
609 { 621 {
610 switchChannel = 0; 622 switchChannel = 0;
611 delayStartTick = tick; 623 delayStartTick = tick;
612 DigitalO2_SelectSensor(activeSensor); 624 DigitalO2_SelectSensor(activeSensor);
613 externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2);
614 tickToTX = COMMAND_TX_DELAY; 625 tickToTX = COMMAND_TX_DELAY;
615 if(tmpSensorDataDiveO2.sensorId == 0)
616 {
617 Comstatus_O2 = UART_O2_REQ_ID;
618 }
619 } 626 }
620 else 627 else
621 { 628 {
629 tickToTX = 0;
622 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10); 630 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
623 } 631 }
624 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); 632 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
625 } 633 }
626 634 }
627 while((rxBuffer[localRX]!=0)) 635 while((rxBuffer[localRX] != BUFFER_NODATA))
628 { 636 {
629 lastReceiveTick = tick; 637 lastReceiveTick = tick;
630 switch(rxState) 638 switch(rxState)
631 { 639 {
632 case O2RX_CONFIRM: if(rxBuffer[localRX] == '#') 640 case O2RX_CONFIRM: if(rxBuffer[localRX] == '#')
641 {
642 cmdReadIndex = 0;
643 errorReadIndex = 0;
644 }
645 if(errorReadIndex < sizeof(errorStr)-1)
646 {
647 if(rxBuffer[localRX] == errorStr[errorReadIndex])
633 { 648 {
634 cmdReadIndex = 0; 649 errorReadIndex++;
635 errorReadIndex = 0;
636 }
637 if(errorReadIndex < sizeof(errorStr)-1)
638 {
639 if(rxBuffer[localRX] == errorStr[errorReadIndex])
640 {
641 errorReadIndex++;
642 }
643 else
644 {
645 errorReadIndex = 0;
646 }
647 } 650 }
648 else 651 else
649 { 652 {
650 respondErrorDetected = 1; 653 errorReadIndex = 0;
651 } 654 }
652 if(rxBuffer[localRX] == cmdString[cmdReadIndex]) 655 }
653 { 656 else
657 {
658 respondErrorDetected = 1;
659 errorReadIndex = 0;
660 }
661 if(rxBuffer[localRX] == cmdString[cmdReadIndex])
662 {
654 cmdReadIndex++; 663 cmdReadIndex++;
655 if(cmdReadIndex == cmdLength - 1) 664 if(cmdReadIndex == cmdLength - 1)
656 { 665 {
657 if((activeSensor == MAX_MUX_CHANNEL)) 666 if((activeSensor == MAX_MUX_CHANNEL))
658 { 667 {
672 digO2Connected = 1; 681 digO2Connected = 1;
673 } 682 }
674 } 683 }
675 tmpRxIdx = 0; 684 tmpRxIdx = 0;
676 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf)); 685 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
686 cmdReadIndex = 0;
677 switch (Comstatus_O2) 687 switch (Comstatus_O2)
678 { 688 {
679 case UART_O2_CHECK: Comstatus_O2 = UART_O2_IDLE; 689 case UART_O2_CHECK: Comstatus_O2 = UART_O2_IDLE;
690 rxState = O2RX_IDLE;
680 break; 691 break;
681 case UART_O2_REQ_ID: rxState = O2RX_GETNR; 692 case UART_O2_REQ_ID: rxState = O2RX_GETNR;
682 break; 693 break;
683 case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE; 694 case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE;
684 break; 695 break;
688 default: Comstatus_O2 = UART_O2_IDLE; 699 default: Comstatus_O2 = UART_O2_IDLE;
689 rxState = O2RX_IDLE; 700 rxState = O2RX_IDLE;
690 break; 701 break;
691 } 702 }
692 } 703 }
704 }
705 else
706 {
707 cmdReadIndex = 0;
693 } 708 }
694 break; 709 break;
695 710
696 case O2RX_GETSTATUS: 711 case O2RX_GETSTATUS:
697 case O2RX_GETTEMP: 712 case O2RX_GETTEMP:
761 else 776 else
762 { /* the following data items are the last of a sensor respond => store temporal data */ 777 { /* the following data items are the last of a sensor respond => store temporal data */
763 switch (rxState) 778 switch (rxState)
764 { 779 {
765 case O2RX_GETSTATUS: StringToInt(tmpRxBuf,&tmpSensorDataDiveO2.status); 780 case O2RX_GETSTATUS: StringToInt(tmpRxBuf,&tmpSensorDataDiveO2.status);
766 externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2); 781 externalInterface_SetSensorData(activeSensor,(uint8_t*)&tmpSensorDataDiveO2);
767 Comstatus_O2 = UART_O2_IDLE; 782 Comstatus_O2 = UART_O2_IDLE;
768 rxState = O2RX_IDLE; 783 rxState = O2RX_IDLE;
769 break; 784 break;
770 case O2RX_GETSUBSENSORS: StringToInt(tmpRxBuf,&tmpData); 785 case O2RX_GETSUBSENSORS: StringToInt(tmpRxBuf,&tmpData);
771 Comstatus_O2 = UART_O2_IDLE; 786 Comstatus_O2 = UART_O2_IDLE;
772 rxState = O2RX_IDLE; 787 rxState = O2RX_IDLE;
773 break; 788 break;
774 case O2RX_HUMIDITY: StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.humidity); /* raw data cycle */ 789 case O2RX_HUMIDITY: StringToInt(tmpRxBuf,(uint32_t*)&tmpSensorDataDiveO2.humidity); /* raw data cycle */
775 externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2); 790 externalInterface_SetSensorData(activeSensor,(uint8_t*)&tmpSensorDataDiveO2);
776 Comstatus_O2 = UART_O2_IDLE; 791 Comstatus_O2 = UART_O2_IDLE;
777 rxState = O2RX_IDLE; 792 rxState = O2RX_IDLE;
778 break; 793 break;
779 case O2RX_GETNR: StringToUInt64((char*)tmpRxBuf,&tmpSensorDataDiveO2.sensorId); 794 case O2RX_GETNR: StringToUInt64((char*)tmpRxBuf,&tmpSensorDataDiveO2.sensorId);
780 externalInterface_SetSensorData(activeSensor+1,(uint8_t*)&tmpSensorDataDiveO2); 795 externalInterface_SetSensorData(activeSensor,(uint8_t*)&tmpSensorDataDiveO2);
781 index = activeSensor; 796 index = activeSensor;
782 Comstatus_O2 = UART_O2_IDLE; 797 Comstatus_O2 = UART_O2_IDLE;
783 rxState = O2RX_IDLE; 798 rxState = O2RX_IDLE;
784 break; 799 break;
785 default: Comstatus_O2 = UART_O2_IDLE; 800 default: Comstatus_O2 = UART_O2_IDLE;
789 } 804 }
790 break; 805 break;
791 default: rxState = O2RX_IDLE; 806 default: rxState = O2RX_IDLE;
792 break; 807 break;
793 808
794 } 809 }
795 rxBuffer[localRX] = 0; 810 rxBuffer[localRX] = BUFFER_NODATA;
796 localRX++; 811 localRX++;
797 rxReadIndex++; 812 rxReadIndex++;
798 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) 813 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
799 { 814 {
800 localRX = 0; 815 localRX = 0;
801 rxReadIndex = 0; 816 rxReadIndex = 0;
802 } 817 }
803 } 818 }
804 819
805 if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */ 820 if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */
806 { 821 {
807 digO2Connected = 0; 822 digO2Connected = 0;
808 if(curAlive == lastAlive) 823 if(curAlive == lastAlive)
809 { 824 {
810 for(index = 0; index < MAX_ADC_CHANNEL; index++) 825 for(index = 0; index < MAX_ADC_CHANNEL; index++)
811 { 826 {
812 if(pmap[index] == SENSOR_DIGO2) 827 if(pmap[index] == SENSOR_DIGO2)
813 { 828 {
814 setExternalInterfaceChannel(index,0.0); 829 setExternalInterfaceChannel(index,0.0);
815 } 830 }
816 } 831 }
817 } 832 }
818 lastAlive = curAlive; 833 lastAlive = curAlive;
819 } 834 }
820 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ 835 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */
821 { 836 {
822 UART_StartDMA_Receiption(); 837 UART_StartDMA_Receiption();
823 }
824 } 838 }
825 } 839 }
826 840
827 void UART_SetDigO2_Channel(uint8_t channel) 841 void UART_SetDigO2_Channel(uint8_t channel)
828 { 842 {
860 rxWriteIndex+=CHUNK_SIZE; 874 rxWriteIndex+=CHUNK_SIZE;
861 if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) 875 if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
862 { 876 {
863 rxWriteIndex = 0; 877 rxWriteIndex = 0;
864 } 878 }
865 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */ 879 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE) || (rxWriteIndex == rxReadIndex)) /* start next transfer if we did not catch up with read index */
866 { 880 {
867 if(externalInterface_isEnabledPower33()) 881 if(externalInterface_GetUARTProtocol() != 0)
868 { 882 {
869 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
870 UART_StartDMA_Receiption(); 883 UART_StartDMA_Receiption();
871 } 884 }
872 } 885 }
873 } 886 }
874 } 887 }