comparison Small_CPU/Src/uart.c @ 781:01b3eb9d55c3

Update real multiplexer implementation: The final multiplexer provides 4 sensor connections instead of three supported by the prototype => A mupping functionality has been introduced to map the 4 possible mux addresses to the three visible O2 sensor slots. In addition the request cycle time is not depending on the number of sensors connected to make sure that all sensors are read within a defined time frame. The error reaction had to be updated to reset mux channels if one of the sensors fails to respond.
author Ideenmodellierer
date Mon, 29 May 2023 18:26:55 +0200
parents 0b5f45448eb6
children 95af969fe0ae
comparison
equal deleted inserted replaced
780:e40790a67165 781:01b3eb9d55c3
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 CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ 29 #define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */
30 #define CHUNKS_PER_BUFFER (5u) 30 #define CHUNKS_PER_BUFFER (5u)
31 #define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */ 31 #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 */
32 UART_HandleTypeDef huart1; 33 UART_HandleTypeDef huart1;
33 34
34 DMA_HandleTypeDef hdma_usart1_rx; 35 DMA_HandleTypeDef hdma_usart1_rx;
35 36
36 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow fariations in buffer read time */ 37 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow fariations in buffer read time */
39 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ 40 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */
40 static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */ 41 static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */
41 static uint8_t digO2Connected = 0; /* Binary indicator if a sensor is connected or not */ 42 static uint8_t digO2Connected = 0; /* Binary indicator if a sensor is connected or not */
42 static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */ 43 static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */
43 static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */ 44 static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */
44 static uint8_t ppO2TargetChannel = 0; /* The OSTC4 supports three slots for visualization of the ppo2. This one is reserved for the digital sensor */
45 45
46 static SSensorDataDiveO2 tmpSensorDataDiveO2; /* intermediate storage for additional sensor data */ 46 static SSensorDataDiveO2 tmpSensorDataDiveO2; /* intermediate storage for additional sensor data */
47 47
48 char tmpRxBuf[30]; 48 char tmpRxBuf[30];
49 uint8_t tmpRxIdx = 0; 49 uint8_t tmpRxIdx = 0;
50 50
51 static uartO2Status_t Comstatus_O2 = UART_O2_INIT; 51 static uartO2Status_t Comstatus_O2 = UART_O2_INIT;
52 static uint8_t activeSensor = 0; 52 static uint8_t activeSensor = 0;
53 static uint8_t sensorMapping[MAX_ADC_CHANNEL]; /* The mapping is used to assign the visible sensor channel to the mux address (DiveO2) */ 53 static uint8_t sensorMapping[MAX_MUX_CHANNEL]; /* The mapping is used to assign the visible sensor channel to the mux address (DiveO2) */
54 54
55 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ 55 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */
56 float LED_ZeroOffset = 0.0; 56 float LED_ZeroOffset = 0.0;
57 float pCO2 = 0.0; 57 float pCO2 = 0.0;
58 /* Exported functions --------------------------------------------------------*/ 58 /* Exported functions --------------------------------------------------------*/
134 indexstr[0] = '~'; 134 indexstr[0] = '~';
135 indexstr[1] = '1'; 135 indexstr[1] = '1';
136 indexstr[2] = 0x0D; 136 indexstr[2] = 0x0D;
137 indexstr[3] = 0x0A; 137 indexstr[3] = 0x0A;
138 138
139 if((channel < MAX_ADC_CHANNEL) && (sensorMapping[channel] != 0xff)) 139 /* Lookup mux address mapped to the provided channel. If no mapping is found the the MUX itself will be selected */
140 { 140 for(muxAddress = 0; muxAddress < MAX_MUX_CHANNEL; muxAddress++)
141 muxAddress = sensorMapping[channel]; 141 {
142 } 142 if(sensorMapping[muxAddress] == channel)
143 else 143 {
144 { 144 break;
145 muxAddress = MAX_ADC_CHANNEL; /* default to mux */ 145 }
146 } 146 }
147 indexstr[1] = '0' + muxAddress; 147 indexstr[1] = muxAddress;
148 HAL_UART_Transmit(&huart1,indexstr,4,10); 148 HAL_UART_Transmit(&huart1,indexstr,4,10);
149 } 149 }
150 150
151 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength) 151 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
152 { 152 {
487 static uint8_t cmdLength = 0; 487 static uint8_t cmdLength = 0;
488 static uint8_t cmdString[10]; 488 static uint8_t cmdString[10];
489 static uint8_t cmdReadIndex = 0; 489 static uint8_t cmdReadIndex = 0;
490 static uint32_t tickToTX = 0; 490 static uint32_t tickToTX = 0;
491 static uint32_t delayStartTick = 0; 491 static uint32_t delayStartTick = 0;
492 static uint16_t requestIntervall = 0;
493 static uint8_t retryRequest = 1;
494 static uint8_t lastComState = 0;
492 495
493 uint8_t switchChannel = 0; 496 uint8_t switchChannel = 0;
494 uint8_t index = 0; 497 uint8_t index = 0;
495 uint32_t tmpO2 = 0; 498 uint32_t tmpO2 = 0;
496 uint32_t tmpData = 0; 499 uint32_t tmpData = 0;
518 curAlive = 0; 521 curAlive = 0;
519 522
520 Comstatus_O2 = UART_O2_CHECK; 523 Comstatus_O2 = UART_O2_CHECK;
521 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); 524 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
522 DigitalO2_SelectSensor(activeSensor); 525 DigitalO2_SelectSensor(activeSensor);
523 if(activeSensor < MAX_ADC_CHANNEL) 526 if(activeSensor < MAX_MUX_CHANNEL)
524 { 527 {
525 externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2); 528 externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2);
526 } 529 }
527 delayStartTick = tick; 530 delayStartTick = tick;
528 tickToTX = COMMAND_TX_DELAY; 531 tickToTX = COMMAND_TX_DELAY;
529 532
530 rxState = O2RX_CONFIRM; 533 rxState = O2RX_CONFIRM;
531 cmdReadIndex = 0; 534 cmdReadIndex = 0;
532 lastO2ReqTick = tick; 535 lastO2ReqTick = tick;
533 536
537 requestIntervall = 0;
538 for(index = 0; index < MAX_MUX_CHANNEL; index++)
539 {
540 if(pmap[index] == SENSOR_DIGO2)
541 {
542 requestIntervall++;
543 }
544 }
545 if(requestIntervall != 0)
546 {
547 requestIntervall = REQUEST_INT_SENSOR_MS / requestIntervall;
548 }
549 else
550 {
551 requestIntervall = REQUEST_INT_SENSOR_MS;
552 }
534 UART_StartDMA_Receiption(); 553 UART_StartDMA_Receiption();
535 } 554 }
536 if(time_elapsed_ms(lastO2ReqTick,tick) > 1000) /* repeat request once per second */ 555 if(time_elapsed_ms(lastO2ReqTick,tick) > requestIntervall) /* repeat request or iterate to next sensor */
537 { 556 {
538 lastO2ReqTick = tick; 557 lastO2ReqTick = tick;
539 index = activeSensor; 558 index = activeSensor;
540 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */ 559 if(lastComState == Comstatus_O2)
541 { 560 {
561 if(retryRequest)
562 {
563 retryRequest = 0;
564 }
565 else /* no answer even repeating the request => abort request */
566 {
567 if(Comstatus_O2 == UART_O2_REQ_RAW)
568 {
569 setExternalInterfaceChannel(activeSensor,0.0);
570 }
571 Comstatus_O2 = UART_O2_IDLE;
572 }
573 }
574 lastComState = Comstatus_O2;
575 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */
576 {
577 retryRequest = 1;
542 if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */ 578 if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */
543 { 579 {
544 if(activeSensor < MAX_ADC_CHANNEL) 580 if(activeSensor < MAX_MUX_CHANNEL)
545 { 581 {
546 do 582 do
547 { 583 {
548 index++; 584 index++;
549 if(index == MAX_ADC_CHANNEL) 585 if(index == MAX_MUX_CHANNEL)
550 { 586 {
551 index = 0; 587 index = 0;
552 } 588 }
553 if(pmap[index] == SENSOR_DIGO2) 589 if(pmap[index] == SENSOR_DIGO2)
554 { 590 {
557 break; 593 break;
558 } 594 }
559 } while(index != activeSensor); 595 } while(index != activeSensor);
560 } 596 }
561 } 597 }
562
563 Comstatus_O2 = UART_O2_REQ_RAW; 598 Comstatus_O2 = UART_O2_REQ_RAW;
564 rxState = O2RX_CONFIRM; 599 rxState = O2RX_CONFIRM;
565 } 600 }
566 if(switchChannel) 601 if(switchChannel)
567 { 602 {
733 if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */ 768 if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */
734 { 769 {
735 digO2Connected = 0; 770 digO2Connected = 0;
736 if(curAlive == lastAlive) 771 if(curAlive == lastAlive)
737 { 772 {
738 setExternalInterfaceChannel(ppO2TargetChannel,0.0); 773 for(index = 0; index < MAX_ADC_CHANNEL; index++)
774 {
775 if(pmap[index] == SENSOR_DIGO2)
776 {
777 setExternalInterfaceChannel(index,0.0);
778 }
779 }
739 } 780 }
740 lastAlive = curAlive; 781 lastAlive = curAlive;
741 } 782 }
742 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ 783 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */
743 { 784 {
746 } 787 }
747 } 788 }
748 789
749 void UART_SetDigO2_Channel(uint8_t channel) 790 void UART_SetDigO2_Channel(uint8_t channel)
750 { 791 {
751 if(channel <= MAX_ADC_CHANNEL) 792 if(channel <= MAX_MUX_CHANNEL)
752 { 793 {
753 activeSensor = channel; 794 activeSensor = channel;
754 } 795 }
755 } 796 }
756 void UART_MapDigO2_Channel(uint8_t channel, uint8_t muxAddress) 797 void UART_MapDigO2_Channel(uint8_t channel, uint8_t muxAddress)
757 { 798 {
758 if((channel < MAX_ADC_CHANNEL) && (muxAddress < MAX_ADC_CHANNEL)) 799 if(((channel < MAX_ADC_CHANNEL) || (channel == 0xff)) && (muxAddress < MAX_MUX_CHANNEL))
759 { 800 {
760 sensorMapping[channel] = muxAddress; 801 sensorMapping[muxAddress] = channel;
761 } 802 }
762 } 803 }
763 804
764 uint8_t UART_isDigO2Connected() 805 uint8_t UART_isDigO2Connected()
765 { 806 {
770 return CO2Connected; 811 return CO2Connected;
771 } 812 }
772 uint8_t UART_isSentinelConnected() 813 uint8_t UART_isSentinelConnected()
773 { 814 {
774 return SentinelConnected; 815 return SentinelConnected;
775 }
776
777 void UART_setTargetChannel(uint8_t channel)
778 {
779 ppO2TargetChannel = channel;
780 } 816 }
781 817
782 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 818 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
783 { 819 {
784 if(huart == &huart1) 820 if(huart == &huart1)