# HG changeset patch # User Ideenmodellierer # Date 1685377615 -7200 # Node ID 01b3eb9d55c302f69a07d25710744c95c7a641fd # Parent e40790a6716529de52a74fb69e1508e4dc8d25c3 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. diff -r e40790a67165 -r 01b3eb9d55c3 Small_CPU/Inc/externalInterface.h --- a/Small_CPU/Inc/externalInterface.h Tue May 23 21:50:19 2023 +0200 +++ b/Small_CPU/Inc/externalInterface.h Mon May 29 18:26:55 2023 +0200 @@ -32,6 +32,7 @@ #define MAX_ADC_CHANNEL (3u) /* number of channels to be read */ +#define MAX_MUX_CHANNEL (4u) /* number of channels provided by the UART multiplexer */ #define EXTERNAL_ADC_NO_DATA 0xFF #define EXT33V_CONTROL_PIN GPIO_PIN_7 /* PortC */ @@ -50,6 +51,7 @@ DETECTION_DIGO2_0, /* check UART channel for connected DigO2 sensor */ DETECTION_DIGO2_1, DETECTION_DIGO2_2, + DETECTION_DIGO2_3, #ifdef ENABLE_CO2_SUPPORT DETECTION_CO2, /* check UART channel for connected CO2 sensor */ #endif diff -r e40790a67165 -r 01b3eb9d55c3 Small_CPU/Src/externalInterface.c --- a/Small_CPU/Src/externalInterface.c Tue May 23 21:50:19 2023 +0200 +++ b/Small_CPU/Src/externalInterface.c Mon May 29 18:26:55 2023 +0200 @@ -335,6 +335,7 @@ || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_0)) || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_1)) || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_2)) + || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2_3)) || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_UARTMUX)) #ifdef ENABLE_CO2_SUPPORT || ((protocol == EXT_INTERFACE_UART_CO2 >> 8) && (externalAutoDetect == DETECTION_CO2)) @@ -464,10 +465,11 @@ void externalInterface_AutodetectSensor() { - static uint8_t tmpMuxMapping[MAX_ADC_CHANNEL]; + static uint8_t tmpMuxMapping[MAX_MUX_CHANNEL]; static uint8_t sensorIndex = 0; static uint8_t uartMuxChannel = 0; uint8_t index = 0; + uint8_t index2 = 0; if(externalAutoDetect != DETECTION_OFF) { @@ -486,6 +488,8 @@ UART_MapDigO2_Channel(index,index); /* request all addresses */ tmpMuxMapping[index] = 0xff; } + UART_MapDigO2_Channel(3,4); + if(externalInterfacePresent) { externalInterface_SwitchPower33(0); @@ -523,7 +527,7 @@ } externalAutoDetect = DETECTION_UARTMUX; externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8); - UART_SetDigO2_Channel(3); + UART_SetDigO2_Channel(MAX_MUX_CHANNEL); break; case DETECTION_UARTMUX: if(UART_isDigO2Connected()) { @@ -536,7 +540,9 @@ break; case DETECTION_DIGO2_0: case DETECTION_DIGO2_1: - case DETECTION_DIGO2_2: if(UART_isDigO2Connected()) + case DETECTION_DIGO2_2: + case DETECTION_DIGO2_3: + if(UART_isDigO2Connected()) { for(index = 0; index < 3; index++) /* lookup a channel which may be used by digO2 */ { @@ -552,11 +558,12 @@ else { tmpSensorMap[index] = SENSOR_DIGO2; - tmpMuxMapping[index] = externalAutoDetect - DETECTION_DIGO2_0; + tmpMuxMapping[externalAutoDetect - DETECTION_DIGO2_0] = index; } - UART_setTargetChannel(index); - - /* tmpSensorMap[sensorIndex++] = SENSOR_DIGO2; */ + } + else + { + UART_MapDigO2_Channel(0xff, externalAutoDetect - DETECTION_DIGO2_0); } if(uartMuxChannel) { @@ -566,7 +573,7 @@ } else { - externalAutoDetect = DETECTION_DIGO2_2; /* skip detection of other serial sensors */ + externalAutoDetect = DETECTION_DIGO2_3; /* skip detection of other serial sensors */ } externalAutoDetect++; #ifdef ENABLE_CO2_SUPPORT @@ -621,9 +628,14 @@ { tmpSensorMap[EXT_INTERFACE_SENSOR_CNT-1] = SENSOR_MUX; } - for(index = 0; index < MAX_ADC_CHANNEL; index++) + index2 = 0; /* used for target channel */ + for(index = 0; index < MAX_MUX_CHANNEL; index++) { - UART_MapDigO2_Channel(index,tmpMuxMapping[index]); + if(tmpMuxMapping[index] != 0xff) + { + UART_MapDigO2_Channel(index2, index); + index2++; + } } externalAutoDetect = DETECTION_OFF; externalInterface_SwitchUART(0); @@ -664,7 +676,6 @@ break; } } - UART_setTargetChannel(index); /* if no slot for digO2 is found then the function will be called with an invalid parameter causing the overwrite function to fail */ } break; default: diff -r e40790a67165 -r 01b3eb9d55c3 Small_CPU/Src/uart.c --- a/Small_CPU/Src/uart.c Tue May 23 21:50:19 2023 +0200 +++ b/Small_CPU/Src/uart.c Mon May 29 18:26:55 2023 +0200 @@ -26,9 +26,10 @@ /* Private variables ---------------------------------------------------------*/ -#define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ -#define CHUNKS_PER_BUFFER (5u) -#define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */ +#define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ +#define CHUNKS_PER_BUFFER (5u) +#define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */ +#define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor */ UART_HandleTypeDef huart1; DMA_HandleTypeDef hdma_usart1_rx; @@ -41,7 +42,6 @@ static uint8_t digO2Connected = 0; /* Binary indicator if a sensor is connected or not */ static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */ static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */ -static uint8_t ppO2TargetChannel = 0; /* The OSTC4 supports three slots for visualization of the ppo2. This one is reserved for the digital sensor */ static SSensorDataDiveO2 tmpSensorDataDiveO2; /* intermediate storage for additional sensor data */ @@ -50,7 +50,7 @@ static uartO2Status_t Comstatus_O2 = UART_O2_INIT; static uint8_t activeSensor = 0; -static uint8_t sensorMapping[MAX_ADC_CHANNEL]; /* The mapping is used to assign the visible sensor channel to the mux address (DiveO2) */ +static uint8_t sensorMapping[MAX_MUX_CHANNEL]; /* The mapping is used to assign the visible sensor channel to the mux address (DiveO2) */ float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ float LED_ZeroOffset = 0.0; @@ -136,15 +136,15 @@ indexstr[2] = 0x0D; indexstr[3] = 0x0A; - if((channel < MAX_ADC_CHANNEL) && (sensorMapping[channel] != 0xff)) + /* Lookup mux address mapped to the provided channel. If no mapping is found the the MUX itself will be selected */ + for(muxAddress = 0; muxAddress < MAX_MUX_CHANNEL; muxAddress++) { - muxAddress = sensorMapping[channel]; + if(sensorMapping[muxAddress] == channel) + { + break; + } } - else - { - muxAddress = MAX_ADC_CHANNEL; /* default to mux */ - } - indexstr[1] = '0' + muxAddress; + indexstr[1] = muxAddress; HAL_UART_Transmit(&huart1,indexstr,4,10); } @@ -489,6 +489,9 @@ static uint8_t cmdReadIndex = 0; static uint32_t tickToTX = 0; static uint32_t delayStartTick = 0; + static uint16_t requestIntervall = 0; + static uint8_t retryRequest = 1; + static uint8_t lastComState = 0; uint8_t switchChannel = 0; uint8_t index = 0; @@ -520,7 +523,7 @@ Comstatus_O2 = UART_O2_CHECK; DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); DigitalO2_SelectSensor(activeSensor); - if(activeSensor < MAX_ADC_CHANNEL) + if(activeSensor < MAX_MUX_CHANNEL) { externalInterface_GetSensorData(activeSensor + 1, (uint8_t*)&tmpSensorDataDiveO2); } @@ -531,22 +534,55 @@ cmdReadIndex = 0; lastO2ReqTick = tick; + requestIntervall = 0; + for(index = 0; index < MAX_MUX_CHANNEL; index++) + { + if(pmap[index] == SENSOR_DIGO2) + { + requestIntervall++; + } + } + if(requestIntervall != 0) + { + requestIntervall = REQUEST_INT_SENSOR_MS / requestIntervall; + } + else + { + requestIntervall = REQUEST_INT_SENSOR_MS; + } UART_StartDMA_Receiption(); } - if(time_elapsed_ms(lastO2ReqTick,tick) > 1000) /* repeat request once per second */ + if(time_elapsed_ms(lastO2ReqTick,tick) > requestIntervall) /* repeat request or iterate to next sensor */ { lastO2ReqTick = tick; index = activeSensor; - if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */ + if(lastComState == Comstatus_O2) { + if(retryRequest) + { + retryRequest = 0; + } + else /* no answer even repeating the request => abort request */ + { + if(Comstatus_O2 == UART_O2_REQ_RAW) + { + setExternalInterfaceChannel(activeSensor,0.0); + } + Comstatus_O2 = UART_O2_IDLE; + } + } + lastComState = Comstatus_O2; + if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */ + { + retryRequest = 1; if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */ { - if(activeSensor < MAX_ADC_CHANNEL) + if(activeSensor < MAX_MUX_CHANNEL) { do { index++; - if(index == MAX_ADC_CHANNEL) + if(index == MAX_MUX_CHANNEL) { index = 0; } @@ -559,7 +595,6 @@ } while(index != activeSensor); } } - Comstatus_O2 = UART_O2_REQ_RAW; rxState = O2RX_CONFIRM; } @@ -735,7 +770,13 @@ digO2Connected = 0; if(curAlive == lastAlive) { - setExternalInterfaceChannel(ppO2TargetChannel,0.0); + for(index = 0; index < MAX_ADC_CHANNEL; index++) + { + if(pmap[index] == SENSOR_DIGO2) + { + setExternalInterfaceChannel(index,0.0); + } + } } lastAlive = curAlive; } @@ -748,16 +789,16 @@ void UART_SetDigO2_Channel(uint8_t channel) { - if(channel <= MAX_ADC_CHANNEL) + if(channel <= MAX_MUX_CHANNEL) { activeSensor = channel; } } void UART_MapDigO2_Channel(uint8_t channel, uint8_t muxAddress) { - if((channel < MAX_ADC_CHANNEL) && (muxAddress < MAX_ADC_CHANNEL)) + if(((channel < MAX_ADC_CHANNEL) || (channel == 0xff)) && (muxAddress < MAX_MUX_CHANNEL)) { - sensorMapping[channel] = muxAddress; + sensorMapping[muxAddress] = channel; } } @@ -774,11 +815,6 @@ return SentinelConnected; } -void UART_setTargetChannel(uint8_t channel) -{ - ppO2TargetChannel = channel; -} - void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart == &huart1)