# HG changeset patch
# User Ideenmodellierer
# Date 1691432984 -7200
# Node ID e9eba334b94224b9d6ff3dc1489dd593e975b74c
# Parent  acf6614dc396d88528789c1a3ef92a7e1953e756
Migrated CO2 protocol implementation to new format:
The previous implementation was a monolithic protocol implementation which was not usable together with the multiplexer. The new implementation moves the CO2 implementation into a separate C file and decoubles the upper layer external interface, which is not able to handle DiveO2 and CO2 sensors in parallel without restriction to port assignments.

diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Inc/externalInterface.h
--- a/Small_CPU/Inc/externalInterface.h	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Inc/externalInterface.h	Mon Aug 07 20:29:44 2023 +0200
@@ -41,7 +41,7 @@
 #define MIN_ADC_VOLTAGE_MV	(5.0f)		/* miminal voltage to rate an ADC channel as active */
 
 #define COMMON_SENSOR_STATE_INIT	(0x0u)	/* All individual state definitions shall start with a INIT state = 0 */
-#define COMMON_SENSOR_STATE_INVALID (0xFFu) /* All individual state devinitions shall not use 0xFF for operation control */
+#define COMMON_SENSOR_STATE_INVALID (0xFFu) /* All individual state definitions shall not use 0xFF for operation control */
 
  typedef enum
  {
@@ -56,7 +56,10 @@
 	DETECTION_DIGO2_2,
 	DETECTION_DIGO2_3,
 #ifdef ENABLE_CO2_SUPPORT
-	DETECTION_CO2,			/* check UART channel for connected CO2 sensor */
+	DETECTION_CO2_0,			/* check UART channel for connected CO2 sensor */
+	DETECTION_CO2_1,
+	DETECTION_CO2_2,
+	DETECTION_CO2_3,
 #endif
 #ifdef ENABLE_SENTINEL_MODE
 	DETECTION_SENTINEL,		/* check UART channel for connected Sentinel */
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Inc/uart.h
--- a/Small_CPU/Inc/uart.h	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Inc/uart.h	Mon Aug 07 20:29:44 2023 +0200
@@ -25,47 +25,9 @@
 #include "stm32f4xx_hal.h"
 
 
-#define BUFFER_NODATA			(7u)		/* The read function needs a byte which indecated that no data for processing is available.*/
+#define BUFFER_NODATA			(7u)		/* The read function needs a byte which indicated that no data for processing is available.*/
 											/* This byte shall never appear in a normal data steam */
 
- typedef enum
- {
- 	UART_CO2_INIT = 0,
-	UART_CO2_SETUP,			/* collecting data needed to be read out of the sensor once at startup */
- 	UART_CO2_OPERATING,		/* normal operation */
- } uartCO2Status_t;
-
- typedef enum
- {
- 	RX_Ready= 0,					/* Initial state */
-	RX_DetectStart,					/* validate start byte */
-	RX_SelectData,					/* Data contained in this frame */
- 	RX_Data0,						/* Process incoming data */
-	RX_Data1,
-	RX_Data2,
-	RX_Data3,
-	RX_Data4,
-	RX_Data5,
-	RX_Data6,
-	RX_Data7,
-	RX_Data8,
-	RX_Data9,
-	RX_Data10,
-	RX_Data11,
-	RX_Data12,
-	RX_DataComplete
- } receiveState_t;
-
-
-typedef enum
-{
-	CO2CMD_MODE_POLL,		/* Set operation mode of sensor to polling => only send data if requested */
-	CO2CMD_MODE_STREAM,		/* Set operation mode of sensor to streaming => send data every two seconds */
-	CO2CMD_CALIBRATE,		/* Calibrate sensor */
-	CO2CMD_GETSCALE,		/* Get scaling factor */
-	CO2CMD_GETDATA			/* Read sensor data */
-} co2SensorCmd_t;
-
 void MX_USART1_UART_Init(void);
 void MX_USART1_UART_DeInit(void);
 void MX_USART1_DMA_Init(void);
@@ -85,7 +47,7 @@
 void UART_SendCmdString(uint8_t *cmdString);
 void UART_ReadData(uint8_t sensorType);
 void UART_FlushRxBuffer(void);
-
+void UART_ChangeBaudrate(uint32_t newBaudrate);
 
 void StringToInt(char *pstr, uint32_t *puInt32);
 void StringToUInt64(char *pstr, uint64_t *puint64);
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Inc/uartProtocol_Co2.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Inc/uartProtocol_Co2.h	Mon Aug 07 20:29:44 2023 +0200
@@ -0,0 +1,81 @@
+/**
+  ******************************************************************************
+  * @file    uartProtocol_Co2.h
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    31-Jul-2023
+  * @brief	 Interface functionality to handle external, UART based CO2 sensors
+  *
+  @verbatim
+  ==============================================================================
+                        ##### How to use #####
+  ==============================================================================
+  @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef UART_PROTOCOL_CO2_H
+#define UART_PROTOCOL_CO2_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "configuration.h"
+#include "stm32f4xx_hal.h"
+
+ typedef enum
+  {
+	UART_CO2_INIT = 0,		/* Default Status for every sensor type */
+	UART_CO2_IDLE,			/* sensor detected and no communication pending */
+	UART_CO2_ERROR,
+ 	UART_CO2_SETUP = 10,	/* collecting data needed to be read out of the sensor once at startup */
+  	UART_CO2_OPERATING,		/* normal operation */
+	UART_CO2_CALIBRATE		/* request calibration */
+  } uartCO2Status_t;
+
+  typedef enum
+  {
+  	RX_Ready= 0,					/* Initial state */
+ 	RX_DetectStart,					/* validate start byte */
+ 	RX_SelectData,					/* Data contained in this frame */
+  	RX_Data0,						/* Process incoming data */
+ 	RX_Data1,
+ 	RX_Data2,
+ 	RX_Data3,
+ 	RX_Data4,
+ 	RX_Data5,
+ 	RX_Data6,
+ 	RX_Data7,
+ 	RX_Data8,
+ 	RX_Data9,
+ 	RX_Data10,
+ 	RX_Data11,
+ 	RX_Data12,
+ 	RX_DataComplete
+  } receiveState_t;
+
+
+ typedef enum
+ {
+ 	CO2CMD_MODE_POLL,		/* Set operation mode of sensor to polling => only send data if requested */
+ 	CO2CMD_MODE_STREAM,		/* Set operation mode of sensor to streaming => send data every two seconds */
+ 	CO2CMD_CALIBRATE,		/* Calibrate sensor */
+ 	CO2CMD_GETSCALE,		/* Get scaling factor */
+ 	CO2CMD_GETDATA			/* Read sensor data */
+ } co2SensorCmd_t;
+
+
+void uartCo2_Control(void);
+void uartCo2_ProcessData(uint8_t data);
+void uartCo2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint8_t *cmdLength);
+uint8_t uartCo2_isSensorConnected();
+
+#endif /* UART_PROTOCOL_CO2_H */
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Inc/uartProtocol_O2.h
--- a/Small_CPU/Inc/uartProtocol_O2.h	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Inc/uartProtocol_O2.h	Mon Aug 07 20:29:44 2023 +0200
@@ -31,17 +31,23 @@
 #include "configuration.h"
 #include "stm32f4xx_hal.h"
 
+ typedef enum
+ {
+ 	UART_COMMON_INIT = 0,	/* Default Status for every sensor type */
+	UART_COMMON_IDLE,		/* sensor detected and no communication pending */
+	UART_COMMON_ERROR,		/* Error message received from sensor */
+ } uartCommonStatus_t;
 
  typedef enum
  {
- 	UART_O2_INIT = 0,
- 	UART_O2_CHECK,			/* send blink command and check if sensor answers */
- 	UART_O2_REQ_INFO,		/* request information about available internal sensors of sensor */
-	UART_O2_REQ_ID,			/* request ID of sensor */
- 	UART_O2_IDLE,			/* sensor detected and no communication pending */
- 	UART_O2_REQ_O2,			/* O2 value has been requested and is in receiption progress */
-	UART_O2_REQ_RAW,		/* Request O2 and extended raw data */
- 	UART_O2_ERROR			/* Error message received from sensor */
+	UART_O2_INIT = UART_COMMON_INIT,		/* Default Status for every sensor type */
+	UART_O2_IDLE = UART_COMMON_IDLE,		/* sensor detected and no communication pending */
+	UART_O2_ERROR = UART_COMMON_ERROR,		/* Error message received from sensor */
+ 	UART_O2_CHECK,							/* send blink command and check if sensor answers */
+ 	UART_O2_REQ_INFO,						/* request information about available internal sensors of sensor */
+	UART_O2_REQ_ID,							/* request ID of sensor */
+ 	UART_O2_REQ_O2,							/* O2 value has been requested and is in receiption progress */
+	UART_O2_REQ_RAW,						/* Request O2 and extended raw data */
  } uartO2Status_t;
 
 
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Src/externalInterface.c
--- a/Small_CPU/Src/externalInterface.c	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Src/externalInterface.c	Mon Aug 07 20:29:44 2023 +0200
@@ -33,6 +33,7 @@
 #include "data_exchange.h"
 #include "pressure.h"
 #include "uartProtocol_O2.h"
+#include "uartProtocol_Co2.h"
 
 extern SGlobal global;
 extern UART_HandleTypeDef huart1;
@@ -133,7 +134,7 @@
 	{
 		externalChannel_mV[index] = 0.0;
 	}
-	memset(externalInterface_SensorState,UART_O2_INIT,sizeof(externalInterface_SensorState));
+	memset(externalInterface_SensorState,UART_COMMON_INIT,sizeof(externalInterface_SensorState));
 }
 
 
@@ -363,13 +364,10 @@
 		case (EXT_INTERFACE_UART_O2 >> 8):
 		case (EXT_INTERFACE_UART_SENTINEL >> 8):
 				if((externalAutoDetect <= DETECTION_START)
-															|| ((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))
+					|| ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect >= DETECTION_UARTMUX) && (externalAutoDetect <= DETECTION_DIGO2_3))
+
 #ifdef ENABLE_CO2_SUPPORT
-															|| ((protocol == EXT_INTERFACE_UART_CO2 >> 8) && (externalAutoDetect == DETECTION_CO2))
+					|| ((externalAutoDetect >= DETECTION_CO2_0) && (externalAutoDetect <= DETECTION_CO2_3))
 #endif
 #ifdef ENABLE_SENTINEL_MODE
 														   || ((protocol == EXT_INTERFACE_UART_SENTINEL >> 8) && (externalAutoDetect == DETECTION_SENTINEL))
@@ -566,8 +564,10 @@
 	uint8_t index2 = 0;
 	uint8_t cntSensor = 0;
 	uint8_t cntUARTSensor = 0;
+#ifdef ENABLE_CO2_SUPPORT
 	uint8_t cmdString[10];
 	uint8_t cmdLength = 0;
+#endif
 
 	if(externalAutoDetect != DETECTION_OFF)
 	{
@@ -583,7 +583,7 @@
 									tmpSensorMap[4] = SENSOR_NONE;
 
 									memset(foundSensorMap, SENSOR_NONE, sizeof(foundSensorMap));
-									memset(externalInterface_SensorState,UART_O2_INIT,sizeof(externalInterface_SensorState));
+									memset(externalInterface_SensorState,UART_COMMON_INIT,sizeof(externalInterface_SensorState));
 									memset(Mux2ADCMap,0, sizeof(Mux2ADCMap));
 
 									if(externalInterfacePresent)
@@ -640,12 +640,11 @@
 											tmpSensorMap[EXT_INTERFACE_SENSOR_CNT-1] = SENSOR_NONE;
 										}
 										externalAutoDetect = DETECTION_DIGO2_0;
-										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
 										UART_MUX_SelectAddress(0);
 										uartO2_SetChannel(0);
 										activeUartChannel = 0;
 										tmpSensorMap[EXT_INTERFACE_MUX_OFFSET] = SENSOR_DIGO2;
-										externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET] = UART_O2_INIT;
+										externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET] = UART_COMMON_INIT;
 										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
 				break;
 			case DETECTION_DIGO2_0:
@@ -661,7 +660,7 @@
 									{
 										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
 										UART_MUX_SelectAddress(uartMuxChannel);
-										externalInterface_SensorState[uartMuxChannel + EXT_INTERFACE_MUX_OFFSET] = UART_O2_INIT;
+										externalInterface_SensorState[uartMuxChannel + EXT_INTERFACE_MUX_OFFSET] = UART_COMMON_INIT;
 										uartO2_SetChannel(uartMuxChannel);
 										activeUartChannel = uartMuxChannel;
 										tmpSensorMap[uartMuxChannel - 1 + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
@@ -678,39 +677,50 @@
 									}
 									externalAutoDetect++;
 #ifdef ENABLE_CO2_SUPPORT
-									if(externalAutoDetect == DETECTION_CO2)
+									if(externalAutoDetect == DETECTION_CO2_0)
 									{
+										UART_MUX_SelectAddress(0);
+										activeUartChannel = 0;
+										tmpSensorMap[uartMuxChannel - 1 + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
+										uartMuxChannel = 1;
+										tmpSensorMap[EXT_INTERFACE_MUX_OFFSET] = SENSOR_CO2;
+										externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET] = UART_COMMON_INIT;
 										externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8);
 										if(tmpSensorMap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)		/* switch sensor operation mode depending on HW config */
 										{
-											DigitalCO2_SendCmd(CO2CMD_MODE_POLL, cmdString, &cmdLength);
+											uartCo2_SendCmd(CO2CMD_MODE_POLL, cmdString, &cmdLength);
 										}
 										else
 										{
-											DigitalCO2_SendCmd(CO2CMD_MODE_STREAM, cmdString, &cmdLength);
+											uartCo2_SendCmd(CO2CMD_MODE_STREAM, cmdString, &cmdLength);
 										}
 									}
 				break;
-			case DETECTION_CO2:		if(UART_isCO2Connected())
+			case DETECTION_CO2_0:
+			case DETECTION_CO2_1:
+			case DETECTION_CO2_2:
+			case DETECTION_CO2_3:	if(uartCo2_isSensorConnected())
+									{
+										foundSensorMap[EXT_INTERFACE_MUX_OFFSET + activeUartChannel] = SENSOR_CO2;
+										externalAutoDetect = DETECTION_DONE;	/* only one CO2 sensor supported */
+									}
+									else if(foundSensorMap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)
 									{
-										for(index = 0; index < 3; index++)	/* lookup a channel which may be used by CO2*/
-										{
-											if(tmpSensorMap[index] == SENSOR_NONE)
-											{
-												break;
-											}
-										}
-										if(index == 3)
-										{
-											tmpSensorMap[sensorIndex++] = SENSOR_CO2;  /* place Co2 sensor behind O2 sensors (not visible) */
-										}
-										else
-										{
-											tmpSensorMap[index] = SENSOR_CO2;
-										}
-
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8);
+										UART_MUX_SelectAddress(uartMuxChannel);
+										activeUartChannel = uartMuxChannel;
+										tmpSensorMap[uartMuxChannel - 1 + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
+										tmpSensorMap[EXT_INTERFACE_MUX_OFFSET + uartMuxChannel] = SENSOR_CO2;
+										externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET + uartMuxChannel] = UART_COMMON_INIT;
+										externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8);
+										uartCo2_SendCmd(CO2CMD_MODE_POLL, cmdString, &cmdLength);
+										externalAutoDetect++;
+										uartMuxChannel++;
 									}
-									externalAutoDetect++;
+									else
+									{
+										externalAutoDetect = DETECTION_DONE;
+									}
 #endif
 #ifdef ENABLE_SENTINEL_MODE
 									if(externalAutoDetect == DETECTION_SENTINEL)
@@ -740,7 +750,7 @@
 									cntUARTSensor = 0;
 									for(index = 0; index < EXT_INTERFACE_SENSOR_CNT-1; index++)
 									{
-										if((foundSensorMap[index] >= SENSOR_ANALOG) && (foundSensorMap[index] < SENSOR_TYPE_O2_END))
+										if((foundSensorMap[index] >= SENSOR_ANALOG) && (foundSensorMap[index] < SENSOR_MUX))
 										{
 											cntSensor++;
 										}
@@ -764,6 +774,21 @@
 											}
 										}
 									}
+									for(index = 0; index < EXT_INTERFACE_SENSOR_CNT-1; index++)
+									{
+										if(foundSensorMap[index] == SENSOR_CO2)
+										{
+											for(index2 = 0; index2 < MAX_ADC_CHANNEL; index2++)
+											{
+												if(foundSensorMap[index2] == SENSOR_NONE)
+												{
+													foundSensorMap[index2] = SENSOR_CO2M;		/* store a mirror instance needed for visualization */
+													Mux2ADCMap[index2] = index;
+													break;
+												}
+											}
+										}
+									}
 									externalInterfaceMuxReqIntervall = 0xFFFF;
 									if(cntSensor == 0)		/* return default sensor map if no sensor at all has been detected */
 									{
@@ -779,7 +804,7 @@
 										}
 									}
 									memcpy(SensorMap, foundSensorMap, sizeof(foundSensorMap));
-									memset(externalInterface_SensorState,UART_O2_INIT,sizeof(externalInterface_SensorState));
+									memset(externalInterface_SensorState, UART_COMMON_INIT, sizeof(externalInterface_SensorState));
 				break;
 			default:
 				break;
@@ -805,7 +830,14 @@
 											SensorMap[index] = SENSOR_SEARCH;
 										}
 			break;
-		case EXT_INTERFACE_CO2_CALIB:	cmdLength = snprintf(cmdString, 10, "G\r\n");
+		case EXT_INTERFACE_CO2_CALIB:	for(index = 0; index < EXT_INTERFACE_SENSOR_CNT; index++)
+										{
+											if(SensorMap[index] == SENSOR_CO2)
+											{
+												externalInterface_SensorState[index] = UART_CO2_CALIBRATE;
+												break;
+											}
+										}
 			break;
 		case EXT_INTERFACE_COPY_SENSORMAP:	if(externalAutoDetect == DETECTION_OFF)
 											{
@@ -877,6 +909,26 @@
 	return newChannel;
 }
 
+void externalInterface_CheckBaudrate(uint8_t sensorType)
+{
+	static uint32_t lastBaudRate = 0;
+	uint32_t newBaudrate = 0;
+
+	switch(sensorType)
+	{
+			case SENSOR_CO2:		newBaudrate = 9600;
+				break;
+			case SENSOR_DIGO2:
+		default:	newBaudrate = 19200;
+			break;
+	}
+	if(lastBaudRate != newBaudrate)
+	{
+		UART_ChangeBaudrate(newBaudrate);
+		lastBaudRate = newBaudrate;
+	}
+}
+
 void externalInterface_HandleUART()
 {
 	static uint8_t retryRequest = 0;
@@ -898,12 +950,13 @@
 		{
 			UART_MUX_SelectAddress(activeUartChannel);
 		}
+		externalInterface_CheckBaudrate(pmap[activeUartChannel + EXT_INTERFACE_MUX_OFFSET]);
 		UART_FlushRxBuffer();
 	}
 
 	if(externalInterfaceMuxReqIntervall != 0xFFFF)
 	{
-		if(externalInterface_SensorState[activeSensorId] == UART_O2_INIT)
+		if(externalInterface_SensorState[activeSensorId] == UART_COMMON_INIT)
 		{
 			lastRequestTick = tick;
 			TriggerTick = tick - 10;	/* just to make sure control is triggered */
@@ -930,9 +983,19 @@
 			timeToTrigger = 1;
 
 			if((externalInterface_SensorState[activeSensorId] == UART_O2_REQ_O2)		/* timeout */
-					|| (externalInterface_SensorState[activeSensorId] == UART_O2_REQ_RAW))
+					|| (externalInterface_SensorState[activeSensorId] == UART_O2_REQ_RAW)
+					|| (externalInterface_SensorState[activeSensorId] == UART_CO2_OPERATING))
 			{
-				setExternalInterfaceChannel(activeSensorId,0.0);
+				switch(pmap[activeSensorId])
+				{
+					case SENSOR_DIGO2: setExternalInterfaceChannel(activeSensorId,0.0);
+						break;
+					case SENSOR_CO2: externalInterface_SetCO2Value(0.0);
+									 externalInterface_SetCO2State(0);
+						break;
+					default:
+						break;
+				}
 			}
 
 			if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX) /* select next sensor if mux is connected */
@@ -944,10 +1007,13 @@
 					{
 						timeToTrigger = 100;
 						activeUartChannel = index;
-						if(pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_DIGO2)
+						if((pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_DIGO2)
+								|| (pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_CO2))
 						{
 							uartO2_SetChannel(activeUartChannel);
+							externalInterface_CheckBaudrate(SENSOR_MUX);
 							UART_MUX_SelectAddress(activeUartChannel);
+							externalInterface_CheckBaudrate(pmap[activeUartChannel + EXT_INTERFACE_MUX_OFFSET]);
 						}
 					}
 				}
@@ -965,8 +1031,10 @@
 				case SENSOR_MUX:
 				case SENSOR_DIGO2:	uartO2_Control();
 					break;
-			//	case SENSOR_CO2:	uartCO2_Control();
+#ifdef ENABLE_CO2_SUPPORT
+				case SENSOR_CO2:	uartCo2_Control();
 					break;
+#endif
 				default:
 					break;
 			}
@@ -976,22 +1044,12 @@
 
 
 #if 0
-#ifdef ENABLE_CO2_SUPPORT
-		if(externalInterface_GetUARTProtocol() & (EXT_INTERFACE_UART_CO2 >> 8))
-		{
-			UART_HandleCO2Data();
-		}
-#endif
 #ifdef ENABLE_SENTINEL_MODE
 		if(externalInterface_GetUARTProtocol() & (EXT_INTERFACE_UART_SENTINEL >> 8))
 		{
 			UART_HandleSentinelData();
 		}
 #endif
-		if(externalInterface_GetUARTProtocol() & (EXT_INTERFACE_UART_O2 >> 8))
-		{
-			UART_HandleDigitalO2();
-		}
 #endif
 
 
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Src/uart.c
--- a/Small_CPU/Src/uart.c	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Src/uart.c	Mon Aug 07 20:29:44 2023 +0200
@@ -21,6 +21,7 @@
 /* Includes ------------------------------------------------------------------*/
 #include "uart.h"
 #include "uartProtocol_O2.h"
+#include "uartProtocol_Co2.h"
 #include "externalInterface.h"
 #include "data_exchange.h"
 #include <string.h>	/* memset */
@@ -42,22 +43,13 @@
 static uint8_t lastCmdIndex;							/* Index of last command which has not been completly received */
 static uint8_t dmaActive;								/* Indicator if DMA reception needs to be started */
 
-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 uartCO2Status_t ComStatus_CO2 = UART_CO2_INIT;
-
-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;
-float pCO2 = 0.0;
 /* Exported functions --------------------------------------------------------*/
 
 
-
-//huart.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), new_baudrate);
-
 void MX_USART1_UART_Init(void)
 {
 /* regular init */	
@@ -71,7 +63,6 @@
   else
   {
 	  huart1.Init.BaudRate = 9600;
-	  ComStatus_CO2 = UART_CO2_INIT;
   }
   huart1.Init.WordLength = UART_WORDLENGTH_8B;
   huart1.Init.StopBits = UART_STOPBITS_1;
@@ -90,7 +81,6 @@
   rxWriteIndex = 0;
   dmaActive = 0;
 
-  CO2Connected = 0;
   SentinelConnected = 0;
 
 }
@@ -157,28 +147,6 @@
 	}
 }
 
-void DigitalCO2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint16_t *cmdLength)
-{
-	switch (CO2Cmd)
-	{
-		case CO2CMD_MODE_POLL:		*cmdLength = snprintf((char*)cmdString, 10, "K 2\r\n");
-				break;
-		case CO2CMD_MODE_STREAM:	*cmdLength = snprintf((char*)cmdString, 10, "K 1\r\n");
-				break;
-		case CO2CMD_CALIBRATE:		*cmdLength = snprintf((char*)cmdString, 10, "G\r\n");
-				break;
-		case CO2CMD_GETDATA:		*cmdLength = snprintf((char*)cmdString, 10, "Q\r\n");
-				break;
-		case CO2CMD_GETSCALE:		*cmdLength = snprintf((char*)cmdString, 10, ".\r\n");
-				break;
-		default: *cmdLength = 0;
-			break;
-	}
-	if(cmdLength != 0)
-	{
-		HAL_UART_Transmit(&huart1,cmdString,*cmdLength,10);
-	}
-}
 
 void StringToInt(char *pstr, uint32_t *puInt32)
 {
@@ -230,154 +198,36 @@
 
 void UART_StartDMA_Receiption()
 {
-	if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+	if(dmaActive == 0)
 	{
-		dmaActive = 1;
+		if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+		{
+			dmaActive = 1;
+		}
 	}
 }
 
-#ifdef ENABLE_CO2_SUPPORT
-void UART_HandleCO2Data(void)
+void UART_ChangeBaudrate(uint32_t newBaudrate)
 {
-	uint8_t localRX = rxReadIndex;
-	static uint8_t dataType = 0;
-	static uint32_t dataValue = 0;
-	static receiveState_t rxState = RX_Ready;
-	static uint32_t lastReceiveTick = 0;
-	static uint32_t lastTransmitTick = 0;
-	static uint8_t cmdString[10];
-	static uint16_t cmdLength = 0;
-
-	uint32_t Tick = HAL_GetTick();
-
-	uint8_t *pmap = externalInterface_GetSensorMapPointer(0);
-
-	if(ComStatus_CO2 == UART_CO2_INIT)
-	{
-		UART_StartDMA_Receiption();
-		ComStatus_CO2 = UART_CO2_SETUP;
-	}
 
-	if(ComStatus_CO2 == UART_CO2_SETUP)
-	{
-		if(time_elapsed_ms(lastTransmitTick,Tick) > 200)
-		{
-			if(externalInterface_GetCO2Scale() == 0.0)
-			{
-				DigitalCO2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
-				lastTransmitTick = Tick;
-			}
-			else
-			{
-				ComStatus_CO2 = UART_CO2_OPERATING;
-			}
-		}
-	}
-	else
-	{
-		if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)		/* sensor is working in polling mode if mux is connected to avoid interference with other sensors */
-		{
-			if(time_elapsed_ms(lastTransmitTick,Tick) > 2000)	/* poll every two seconds */
-			{
-				lastTransmitTick = Tick;
-				if(cmdLength == 0)							/* poll data */
-				{
-					DigitalCO2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
-				}
-				else											/* resend last command */
-				{
-					HAL_UART_Transmit(&huart1,cmdString,strlen((char*)cmdString),10);
-					cmdLength = 0;
-				}
-			}
-		}
-	}
-	while((rxBuffer[localRX]!=BUFFER_NODATA))
+//	HAL_DMA_Abort(&hdma_usart1_rx);
+		MX_USART1_UART_DeInit();
+		//HAL_UART_Abort(&huart1);
+		//HAL_DMA_DeInit(&hdma_usart1_rx);
+
+
+//	huart1.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq()/2, newBaudrate);
+	huart1.Init.BaudRate = newBaudrate;
+	HAL_UART_Init(&huart1);
+	MX_USART1_DMA_Init();
+	if(dmaActive)
 	{
-		lastReceiveTick = Tick;
-		if(rxState == RX_Ready)		/* identify data content */
-		{
-			switch(rxBuffer[localRX])
-			{
-				case 'l':
-				case 'D':
-				case 'Z':
-				case '.':
-									dataType = rxBuffer[localRX];
-									rxState = RX_Data0;
-									dataValue = 0;
-					break;
-
-				default:			/* unknown or corrupted => ignore */
-					break;
-			}
-		}
-		else if((rxBuffer[localRX] >= '0') && (rxBuffer[localRX] <= '9'))
-		{
-			if((rxState >= RX_Data0) && (rxState <= RX_Data4))
-			{
-				dataValue = dataValue * 10 + (rxBuffer[localRX] - '0');
-				rxState++;
-				if(rxState == RX_Data5)
-				{
-					rxState = RX_DataComplete;
-					CO2Connected = 1;
-				}
-			}
-			else	/* protocol error data has max 5 digits */
-			{
-				rxState = RX_Ready;
-			}
-		}
-		if((rxBuffer[localRX] == ' ') || (rxBuffer[localRX] == '\n'))	/* Abort data detection */
-		{
-			if(rxState == RX_DataComplete)
-			{
-				if(externalInterface_GetCO2State() == 0)
-				{
-					externalInterface_SetCO2State(EXT_INTERFACE_33V_ON);
-				}
-				switch(dataType)
-				{
-					case 'D':			externalInterface_SetCO2SignalStrength(dataValue);
-						break;
-					case 'l':			LED_ZeroOffset = dataValue;
-						break;
-					case 'Z':			externalInterface_SetCO2Value(dataValue);
-						break;
-					case '.':			externalInterface_SetCO2Scale(dataValue);
-						break;
-					default:			rxState = RX_Ready;
-						break;
-				}
-			}
-			if(rxState != RX_Data0)	/* reset state machine because message in wrong format */
-			{
-				rxState = RX_Ready;
-			}
-		}
-		rxBuffer[localRX] = BUFFER_NODATA;
-		localRX++;
-		rxReadIndex++;
-		if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-		{
-			localRX = 0;
-			rxReadIndex = 0;
-		}
-	}
-
-	if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000)	/* check for communication timeout */
-	{
-		externalInterface_SetCO2State(0);
-		CO2Connected = 0;
-	}
-
-	if((dmaActive == 0)	&& (externalInterface_isEnabledPower33()))	/* Should never happen in normal operation => restart in case of communication error */
-	{
+		rxReadIndex = 0;
+		rxWriteIndex = 0;
+		dmaActive = 0;
 		UART_StartDMA_Receiption();
 	}
 }
-#endif
 
 #ifdef ENABLE_SENTINEL_MODE
 void UART_HandleSentinelData(void)
@@ -531,10 +381,7 @@
 #endif
 
 
-uint8_t UART_isCO2Connected()
-{
-	return CO2Connected;
-}
+
 uint8_t UART_isSentinelConnected()
 {
 	return SentinelConnected;
@@ -571,8 +418,10 @@
 			case SENSOR_MUX:
 			case SENSOR_DIGO2:	uartO2_ProcessData(rxBuffer[localRX]);
 				break;
-	//	case SENSOR_CO2:	uartCO2_Control();
+#ifdef ENABLE_CO2_SUPPORT
+			case SENSOR_CO2:	uartCo2_ProcessData(rxBuffer[localRX]);
 				break;
+#endif
 			default:
 				break;
 		}
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Src/uartProtocol_Co2.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Src/uartProtocol_Co2.c	Mon Aug 07 20:29:44 2023 +0200
@@ -0,0 +1,207 @@
+/**
+  ******************************************************************************
+  * @file    uartProtocol_Co2.c
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    31-Jul-2023
+  * @brief   Interface functionality to external, UART based CO2 sensors
+  *
+  @verbatim
+
+
+  @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2023 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+/* Includes ------------------------------------------------------------------*/
+
+#include <string.h>
+#include <uartProtocol_Co2.h>
+#include "uart.h"
+#include "externalInterface.h"
+
+
+#ifdef ENABLE_CO2_SUPPORT
+static uint8_t CO2Connected = 0;						/* Binary indicator if a sensor is connected or not */
+static receiveState_t rxState = RX_Ready;
+
+
+
+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;
+float pCO2 = 0.0;
+
+
+
+void uartCo2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint8_t *cmdLength)
+{
+	switch (CO2Cmd)
+	{
+		case CO2CMD_MODE_POLL:		*cmdLength = snprintf((char*)cmdString, 10, "K 2\r\n");
+				break;
+		case CO2CMD_MODE_STREAM:	*cmdLength = snprintf((char*)cmdString, 10, "K 1\r\n");
+				break;
+		case CO2CMD_CALIBRATE:		*cmdLength = snprintf((char*)cmdString, 10, "G\r\n");
+				break;
+		case CO2CMD_GETDATA:		*cmdLength = snprintf((char*)cmdString, 10, "Q\r\n");
+				break;
+		case CO2CMD_GETSCALE:		*cmdLength = snprintf((char*)cmdString, 10, ".\r\n");
+				break;
+		default: *cmdLength = 0;
+			break;
+	}
+	if(cmdLength != 0)
+	{
+		UART_SendCmdString(cmdString);
+	}
+}
+
+
+void uartCo2_Control(void)
+{
+	static uint8_t cmdString[10];
+	static uint8_t cmdLength = 0;
+	static uint8_t lastComState = 0;
+
+	uint8_t activeSensor = externalInterface_GetActiveUartSensor();
+	uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+
+	uint8_t *pmap = externalInterface_GetSensorMapPointer(0);
+
+
+	if(localComState == UART_CO2_ERROR)
+	{
+		localComState = lastComState;
+	}
+
+	if(localComState == UART_CO2_INIT)
+	{
+		externalInterface_SetCO2Scale(0.0);
+		UART_StartDMA_Receiption();
+		localComState = UART_CO2_SETUP;
+	}
+	if(localComState == UART_CO2_SETUP)
+	{
+		if(externalInterface_GetCO2Scale() == 0.0)
+		{
+			uartCo2_SendCmd(CO2CMD_GETSCALE, cmdString, &cmdLength);
+		}
+		else
+		{
+			localComState = UART_CO2_IDLE;
+		}
+	}
+	else
+	{
+		if(localComState == UART_CO2_CALIBRATE)
+		{
+			uartCo2_SendCmd(CO2CMD_CALIBRATE, cmdString, &cmdLength);
+		}
+		else if(pmap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)		/* sensor is working in polling mode if mux is connected to avoid interference with other sensors */
+		{
+			//if(cmdLength == 0)							/* poll data */
+			if(localComState == UART_CO2_IDLE)
+			{
+				uartCo2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
+				localComState = UART_CO2_OPERATING;
+			}
+			else											/* resend last command */
+			{
+				UART_SendCmdString(cmdString);
+				cmdLength = 0;
+			}
+		}
+		else
+		{
+			localComState = UART_CO2_OPERATING;					/* sensor in streaming mode if not connected to mux => operating */
+		}
+	}
+	lastComState = localComState;
+	externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
+}
+
+
+void uartCo2_ProcessData(uint8_t data)
+{
+	static uint8_t dataType = 0;
+	static uint32_t dataValue = 0;
+	uint8_t activeSensor = externalInterface_GetActiveUartSensor();
+	uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+
+	if(rxState == RX_Ready)		/* identify data content */
+	{
+		switch(data)
+		{
+			case 'G':
+			case 'l':
+			case 'D':
+			case 'Z':
+			case '.':			dataType = data;
+								rxState = RX_Data0;
+								dataValue = 0;
+				break;
+			case '?':			localComState = UART_CO2_ERROR;
+				break;
+			default:			/* unknown or corrupted => ignore */
+					break;
+		}
+	}
+	else if((data >= '0') && (data <= '9'))
+	{
+		if((rxState >= RX_Data0) && (rxState <= RX_Data4))
+		{
+			dataValue = dataValue * 10 + (data - '0');
+			rxState++;
+			if(rxState == RX_Data5)
+			{
+				rxState = RX_DataComplete;
+				CO2Connected = 1;
+			}
+		}
+		else	/* protocol error data has max 5 digits */
+		{
+			rxState = RX_Ready;
+		}
+	}
+	if((data == ' ') || (data == '\n'))	/* Abort data detection */
+	{
+		if(rxState == RX_DataComplete)
+		{
+			localComState = UART_CO2_IDLE;
+			if(externalInterface_GetCO2State() == 0)
+			{
+				externalInterface_SetCO2State(EXT_INTERFACE_33V_ON);
+			}
+			switch(dataType)
+			{
+				case 'D':			externalInterface_SetCO2SignalStrength(dataValue);
+					break;
+				case 'l':			LED_ZeroOffset = dataValue;
+					break;
+				case 'Z':			externalInterface_SetCO2Value(dataValue);
+					break;
+				case '.':			externalInterface_SetCO2Scale(dataValue);
+					break;
+				default:			rxState = RX_Ready;
+					break;
+			}
+		}
+		if(rxState != RX_Data0)	/* reset state machine because message in wrong format */
+		{
+			rxState = RX_Ready;
+		}
+	}
+	externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
+}
+
+uint8_t uartCo2_isSensorConnected()
+{
+	return CO2Connected;
+}
+
+#endif
+
diff -r acf6614dc396 -r e9eba334b942 Small_CPU/Src/uartProtocol_O2.c
--- a/Small_CPU/Src/uartProtocol_O2.c	Mon Jul 31 20:10:27 2023 +0200
+++ b/Small_CPU/Src/uartProtocol_O2.c	Mon Aug 07 20:29:44 2023 +0200
@@ -49,9 +49,9 @@
 					break;
 		case UART_O2_REQ_ID: 	*cmdLength = snprintf((char*)cmdString, 10, "#IDNR");
 			break;
-		case UART_O2_REQ_O2: 	*cmdLength = snprintf((char*)cmdString, 10, "#DOXY");
+		case UART_O2_REQ_O2: 	*cmdLength = snprintf((char*)cmdString, 10, "#MOXY");
 			break;
-		case UART_O2_REQ_RAW:	*cmdLength = snprintf((char*)cmdString, 10, "#DRAW");
+		case UART_O2_REQ_RAW:	*cmdLength = snprintf((char*)cmdString, 10, "#MRAW");
 			break;
 		default: *cmdLength = 0;
 			break;
@@ -99,7 +99,7 @@
 		UART_FlushRxBuffer();
 	}
 
-	if(localComState == UART_O2_INIT)
+	if(localComState == UART_COMMON_INIT)
 	{
 		memset((char*) &tmpSensorDataDiveO2, 0, sizeof(tmpSensorDataDiveO2));
 		externalInterface_SetSensorData(0xFF,(uint8_t*)&tmpSensorDataDiveO2);