changeset 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 e40790a67165
children 9a1bb9e7cb61
files Small_CPU/Inc/externalInterface.h Small_CPU/Src/externalInterface.c Small_CPU/Src/uart.c
diffstat 3 files changed, 87 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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:
--- 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)