changeset 932:effadaa3a1f7 Evo_2_23

Cleanup Gnss UART implementation: The first draft of the internal UART implementation was just a copy of the external UART handling. To avoid duplicated code and maintainance issue both UARTs (external/internal 6/1) share the same functions. To enable this a control structure has to be used as function input which defines the none shared resources like DMA control and rx/tx buffers
author Ideenmodellierer
date Sat, 07 Dec 2024 21:28:08 +0100
parents 5a9bc2e6112d
children 43055e069bd1
files Small_CPU/Inc/uart.h Small_CPU/Inc/uartProtocol_GNSS.h Small_CPU/Inc/uart_Internal.h Small_CPU/Src/GNSS.c Small_CPU/Src/baseCPU2.c Small_CPU/Src/externalInterface.c Small_CPU/Src/scheduler.c Small_CPU/Src/uart.c Small_CPU/Src/uartProtocol_Co2.c Small_CPU/Src/uartProtocol_GNSS.c Small_CPU/Src/uartProtocol_O2.c Small_CPU/Src/uartProtocol_Sentinel.c Small_CPU/Src/uart_Internal.c
diffstat 13 files changed, 347 insertions(+), 722 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/uart.h	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Inc/uart.h	Sat Dec 07 21:28:08 2024 +0100
@@ -28,6 +28,27 @@
 #define BUFFER_NODATA_LOW	(0x15)		/* The read function needs a signiture which indicates that no data for processing is available.*/
 #define BUFFER_NODATA_HIGH  (0xA5)
 
+#define TX_BUF_SIZE				(40u)		/* max length for commands */
+#define CHUNK_SIZE				(80u)		/* the DMA will handle chunk size transfers */
+#define CHUNKS_PER_BUFFER		(3u)
+
+ typedef struct
+ {
+	 UART_HandleTypeDef* pHandle;						/* Pointer to UART handle structure */
+
+	 uint8_t* pRxBuffer;								/* Pointer to receive buffer */
+	 uint8_t* pTxBuffer;								/* Pointer to transmit buffer */
+	 uint8_t* pTxQue;									/* Pointer to transmit que */
+	 uint8_t rxWriteIndex	;							/* Index of the data item which is analyzed */
+	 uint8_t rxReadIndex;								/* Index at which new data is stared */
+	 uint8_t txBufferQueLen;							/* Length of qued data waiting for transmission */
+
+	 uint8_t dmaRxActive;								/* Indicator if DMA reception needs to be started */
+	 uint8_t dmaTxActive;								/* Indicator if DMA reception needs to be started */
+
+ } sUartComCtrl;
+
+extern sUartComCtrl Uart1Ctrl;
 
 UART_HandleTypeDef huart1;
 
@@ -41,7 +62,7 @@
 void GNSS_IO_init(void);
 
 uint8_t UART_ButtonAdjust(uint8_t *array);
-void UART_StartDMA_Receiption(void);
+void UART_StartDMA_Receiption(sUartComCtrl* pUartCtrl);
 #ifdef ENABLE_CO2_SUPPORT
 void UART_HandleCO2Data(void);
 void DigitalCO2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint8_t *cmdLength);
@@ -53,7 +74,9 @@
 #ifdef ENABLE_SENTINEL_MODE
 void UART_HandleSentinelData(void);
 #endif
-void UART_clearRxBuffer(void);
+void UART_SetGnssCtrl(sUartComCtrl* pTarget);
+sUartComCtrl* UART_GetGnssCtrl();
+void UART_clearRxBuffer(sUartComCtrl* pUartCtrl);
 uint8_t UART_isCO2Connected();
 uint8_t UART_isSentinelConnected();
 void UART_setTargetChannel(uint8_t channel);
@@ -61,10 +84,11 @@
 void UART_SendCmdString(uint8_t *cmdString);
 void UART_SendCmdUbx(const uint8_t *cmd, uint8_t len);
 void UART_ReadData(uint8_t sensorType);
-void UART_WriteData(void);
+void UART_WriteData(sUartComCtrl* pUartCtrl);
 void UART_FlushRxBuffer(void);
 void UART_ChangeBaudrate(uint32_t newBaudrate);
 uint8_t UART_isComActive(uint8_t sensorId);
+uint8_t UART_isEndIndication(sUartComCtrl* pCtrl, uint8_t index);
 
 void StringToInt(char *pstr, uint32_t *puInt32);
 void StringToUInt64(char *pstr, uint64_t *puint64);
--- a/Small_CPU/Inc/uartProtocol_GNSS.h	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Inc/uartProtocol_GNSS.h	Sat Dec 07 21:28:08 2024 +0100
@@ -80,7 +80,8 @@
     uint8_t id;
   } gnssRequest_s;
 
-
+uartGnssStatus_t uartGnss_GetState(void);
+void uartGnss_SetState(uartGnssStatus_t newState);
 void uartGnss_Control(void);
 void uartGnss_ProcessData(uint8_t data);
 uint8_t uartGnss_isSensorConnected();
--- a/Small_CPU/Inc/uart_Internal.h	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Inc/uart_Internal.h	Sat Dec 07 21:28:08 2024 +0100
@@ -24,11 +24,6 @@
 
 #include "stm32f4xx_hal.h"
 
-
-#define BUFFER_NODATA_LOW	(0x15)		/* The read function needs a signature which indicates that no data for processing is available.*/
-#define BUFFER_NODATA_HIGH  (0xA5)
-
-
 UART_HandleTypeDef huart6;
 
 void MX_USART6_UART_Init(void);
@@ -36,13 +31,7 @@
 void MX_USART6_UART_DeInit(void);
 void GNSS_IO_init(void);
 
-void UART6_StartDMA_Receiption(void);
-
-void UART_clearRx6Buffer(void);
-void UART6_SendCmdUbx(const uint8_t *cmd, uint8_t len);
-void UART6_ReadData(void);
-void UART6_WriteData(void);
-void UART6_Gnss_ProcessData(uint8_t data);
+void UART6_HandleUART();
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Src/GNSS.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/GNSS.c	Sat Dec 07 21:28:08 2024 +0100
@@ -59,76 +59,6 @@
 }
 
 /*!
- * Searching for a header in data buffer and matching class and message ID to buffer data.
- * @param GNSS Pointer to main GNSS structure.
- */
-uint8_t GNSS_ParseBuffer(GNSS_StateHandle *GNSS) {
-
-	uint8_t DataReceived = 0;
-
-	for (int var = 0; var <= 100; ++var) {
-		if (GNSS->uartWorkingBuffer[var] == 0xB5
-				&& GNSS->uartWorkingBuffer[var + 1] == 0x62) {
-			DataReceived = 1;
-			if (GNSS->uartWorkingBuffer[var + 2] == 0x27
-					&& GNSS->uartWorkingBuffer[var + 3] == 0x03) { //Look at: 32.19.1.1 u-blox 8 Receiver description
-				GNSS_ParseUniqID(GNSS);
-			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
-					&& GNSS->uartWorkingBuffer[var + 3] == 0x21) { //Look at: 32.17.14.1 u-blox 8 Receiver description
-				GNSS_ParseNavigatorData(GNSS);
-			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
-					&& GNSS->uartWorkingBuffer[var + 3] == 0x07) { //ook at: 32.17.30.1 u-blox 8 Receiver description
-				GNSS_ParsePVTData(GNSS);
-			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
-					&& GNSS->uartWorkingBuffer[var + 3] == 0x02) { // Look at: 32.17.15.1 u-blox 8 Receiver description
-				GNSS_ParsePOSLLHData(GNSS);
-			}
-		}
-	}
-	return DataReceived;
-}
-
-/*!
- * Make request for unique chip ID data.
- * @param GNSS Pointer to main GNSS structure.
- */
-void GNSS_GetUniqID(GNSS_StateHandle *GNSS) {
-	HAL_UART_Transmit_DMA(GNSS->huart, getDeviceID,
-			sizeof(getDeviceID) / sizeof(uint8_t));
-	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 17);
-}
-
-/*!
- * Make request for UTC time solution data.
- * @param GNSS Pointer to main GNSS structure.
- */
-void GNSS_GetNavigatorData(GNSS_StateHandle *GNSS) {
-	HAL_UART_Transmit_DMA(GNSS->huart, getNavigatorData,
-			sizeof(getNavigatorData) / sizeof(uint8_t));
-	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 28);
-}
-
-/*!
- * Make request for geodetic position solution data.
- * @param GNSS Pointer to main GNSS structure.
- */
-void GNSS_GetPOSLLHData(GNSS_StateHandle *GNSS) {
-	HAL_UART_Transmit_DMA(GNSS->huart, getPOSLLHData,
-			sizeof(getPOSLLHData) / sizeof(uint8_t));
-	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 36);
-}
-
-/*!
- * Make request for navigation position velocity time solution data.
- * @param GNSS Pointer to main GNSS structure.
- */
-void GNSS_GetPVTData(GNSS_StateHandle *GNSS) {
-	HAL_UART_Transmit_DMA(GNSS->huart, getPVTData,
-			sizeof(getPVTData) / sizeof(uint8_t));
-	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 100);
-}
-
-/*!
  * Parse data to unique chip ID standard.
  * Look at: 32.19.1.1 u-blox 8 Receiver description
  * @param GNSS Pointer to main GNSS structure.
@@ -140,33 +70,6 @@
 }
 
 /*!
- * Changing the GNSS mode.
- * Look at: 32.10.19 u-blox 8 Receiver description
- */
-void GNSS_SetMode(GNSS_StateHandle *GNSS, short gnssMode) {
-	if (gnssMode == 0) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setPortableMode,sizeof(setPortableMode) / sizeof(uint8_t));
-	} else if (gnssMode == 1) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setStationaryMode,sizeof(setStationaryMode) / sizeof(uint8_t));
-	} else if (gnssMode == 2) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setPedestrianMode,sizeof(setPedestrianMode) / sizeof(uint8_t));
-	} else if (gnssMode == 3) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t));
-	} else if (gnssMode == 4) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t));
-	} else if (gnssMode == 5) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone1GMode,sizeof(setAirbone1GMode) / sizeof(uint8_t));
-	} else if (gnssMode == 6) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone2GMode,sizeof(setAirbone2GMode) / sizeof(uint8_t));
-	} else if (gnssMode == 7) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone4GMode,sizeof(setAirbone4GMode) / sizeof(uint8_t));
-	} else if (gnssMode == 8) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setWirstMode,sizeof(setWirstMode) / sizeof(uint8_t));
-	} else if (gnssMode == 9) {
-		HAL_UART_Transmit_DMA(GNSS->huart, setBikeMode,sizeof(setBikeMode) / sizeof(uint8_t));
-	}
-}
-/*!
  * Parse data to navigation position velocity time solution standard.
  * Look at: 32.17.15.1 u-blox 8 Receiver description.
  * @param GNSS Pointer to main GNSS structure.
@@ -341,34 +244,3 @@
 	}
 	GNSS->vAcc = uLong.uLong;
 }
-
-/*!
- *  Sends the basic configuration: Activation of the UBX standard, change of NMEA version to 4.10 and turn on of the Galileo system.
- * @param GNSS Pointer to main GNSS structure.
- */
-void GNSS_LoadConfig(GNSS_StateHandle *GNSS) {
-	HAL_UART_Transmit_DMA(GNSS->huart, configUBX,
-			sizeof(configUBX) / sizeof(uint8_t));
-	HAL_Delay(250);
-	HAL_UART_Transmit_DMA(GNSS->huart, setNMEA410,
-			sizeof(setNMEA410) / sizeof(uint8_t));
-	HAL_Delay(250);
-	HAL_UART_Transmit_DMA(GNSS->huart, setGNSS,
-			sizeof(setGNSS) / sizeof(uint8_t));
-	HAL_Delay(250);
-}
-
-
-
-/*!
- *  Creates a checksum based on UBX standard.
- * @param class Class value from UBX doc.
- * @param messageID MessageID value from UBX doc.
- * @param dataLength Data length value from UBX doc.
- * @param payload Just payload.
- * @return  Returns checksum.
- */
-uint8_t GNSS_Checksum(uint8_t class, uint8_t messageID, uint8_t dataLength,uint8_t *payload) {
-//todo: Look at 32.4 UBX Checksum
-	return 0;
-}
--- a/Small_CPU/Src/baseCPU2.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/baseCPU2.c	Sat Dec 07 21:28:08 2024 +0100
@@ -448,6 +448,10 @@
 			GPIO_GPS_BCKP_ON();
 			MX_USART6_UART_Init();
 			GNSS_Init(&GNSS_Handle, &huart6);
+#else
+#ifdef  ENABLE_GNSS_SUPPORT
+			GNSS_Init(&GNSS_Handle, &huart1);
+#endif
 #endif
 
 /*
--- a/Small_CPU/Src/externalInterface.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/externalInterface.c	Sat Dec 07 21:28:08 2024 +0100
@@ -39,6 +39,7 @@
 
 extern SGlobal global;
 extern UART_HandleTypeDef huart1;
+extern sUartComCtrl Uart1Ctrl;
 
 #define ADC_ANSWER_LENGTH		(5u)		/* 3424 will provide addr + 4 data bytes */
 #define ADC_TIMEOUT				(10u)		/* conversion stuck for unknown reason => restart */
@@ -936,7 +937,7 @@
 										tmpSensorMap[EXT_INTERFACE_MUX_OFFSET] = SENSOR_SENTINEL;
 										externalInterface_SwitchUART(EXT_INTERFACE_UART_SENTINEL);
 										externalInterface_CheckBaudrate(SENSOR_SENTINEL);
-										UART_StartDMA_Receiption();
+										UART_StartDMA_Receiption(&Uart1Ctrl);
 									}
 				break;
 
@@ -1144,7 +1145,7 @@
 		if(externalInterface_SensorState[activeSensorId] != UART_COMMON_INIT)
 		{
 			UART_ReadData(pmap[activeSensorId]);
-			UART_WriteData();
+			UART_WriteData(&Uart1Ctrl);
 		}
 		if(externalInterface_SensorState[activeSensorId] == UART_COMMON_INIT)
 		{
@@ -1175,7 +1176,8 @@
 			if((externalInterface_SensorState[activeSensorId] == UART_O2_REQ_O2)		/* timeout */
 					|| (externalInterface_SensorState[activeSensorId] == UART_O2_REQ_RAW)
 					|| (externalInterface_SensorState[activeSensorId] == UART_CO2_OPERATING)
-					|| (externalInterface_SensorState[activeSensorId] == UART_GNSS_GET_PVT))
+					|| (externalInterface_SensorState[activeSensorId] == UART_GNSS_GET_PVT)
+					|| (externalInterface_SensorState[activeSensorId] == UART_GNSS_GET_SAT))
 			{
 				forceMuxChannel = 1;
 				externalInterface_SensorState[activeSensorId] = UART_O2_IDLE;
--- a/Small_CPU/Src/scheduler.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/scheduler.c	Sat Dec 07 21:28:08 2024 +0100
@@ -43,6 +43,7 @@
 #include "tm_stm32f4_otp.h"
 #include "externalInterface.h"
 #include "uart.h"
+#include "uart_Internal.h"
 #include "GNSS.h"
 #include "uartProtocol_GNSS.h"
 #include "math.h"
--- a/Small_CPU/Src/uart.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uart.c	Sat Dec 07 21:28:08 2024 +0100
@@ -30,49 +30,50 @@
 
 #ifdef ENABLE_GPIO_V2
 extern UART_HandleTypeDef huart6;
-extern void UART6_RxCpltCallback(UART_HandleTypeDef *huart);
-extern void UART6_TxCpltCallback(UART_HandleTypeDef *huart);
+extern sUartComCtrl Uart6Ctrl;
 #endif
 
 /* Private variables ---------------------------------------------------------*/
 
-
-#define TX_BUF_SIZE				(40u)		/* max length for commands */
-#define CHUNK_SIZE				(25u)		/* the DMA will handle chunk size transfers */
-#define CHUNKS_PER_BUFFER		(6u)
-
-
-
 DMA_HandleTypeDef  hdma_usart1_rx, hdma_usart1_tx;
 
 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow variations in buffer read time */
 uint8_t txBuffer[CHUNK_SIZE];							/* tx uses less bytes */
 uint8_t txBufferQue[TX_BUF_SIZE];						/* In MUX mode command may be send shortly after each other => allow q 1 entry que */
-uint8_t txBufferQueLen;
+
 
-static uint8_t rxWriteIndex;							/* Index of the data item which is analysed */
-static uint8_t rxReadIndex;								/* Index at which new data is stared */
 static uint8_t lastCmdIndex;							/* Index of last command which has not been completely received */
-static uint8_t dmaRxActive;								/* Indicator if DMA reception needs to be started */
-static uint8_t dmaTxActive;								/* Indicator if DMA reception needs to be started */
+
+sUartComCtrl Uart1Ctrl;
+static  sUartComCtrl* pGnssCtrl = NULL;
 
 static uint32_t LastCmdRequestTick = 0;					/* Used by ADC handler to avoid interferance with UART communication */
 
-static uint8_t isEndIndication(uint8_t index);
-
 /* Exported functions --------------------------------------------------------*/
 
-void UART_clearRxBuffer(void)
+
+void UART_SetGnssCtrl(sUartComCtrl* pTarget)
+{
+	pGnssCtrl = pTarget;
+}
+
+sUartComCtrl* UART_GetGnssCtrl()
+{
+	return pGnssCtrl;
+}
+
+
+void UART_clearRxBuffer(sUartComCtrl* pUartCtrl)
 {
 	uint16_t index = 0;
 	do
 	{
-		rxBuffer[index++] = BUFFER_NODATA_LOW;
-		rxBuffer[index++] = BUFFER_NODATA_HIGH;
+		pUartCtrl->pRxBuffer[index++] = BUFFER_NODATA_LOW;
+		pUartCtrl->pRxBuffer[index++] = BUFFER_NODATA_HIGH;
 	} while (index < sizeof(rxBuffer));
 
-	rxReadIndex = 0;
-	rxWriteIndex = 0;
+	pUartCtrl->rxReadIndex = 0;
+	pUartCtrl->rxWriteIndex = 0;
 }
 
 void MX_USART1_UART_Init(void)
@@ -91,13 +92,21 @@
 
   MX_USART1_DMA_Init();
 
-  UART_clearRxBuffer();
-  rxReadIndex = 0;
+  UART_clearRxBuffer(&Uart1Ctrl);
   lastCmdIndex = 0;
-  rxWriteIndex = 0;
-  dmaRxActive = 0;
-  dmaTxActive = 0;
-  txBufferQueLen = 0;
+
+  Uart1Ctrl.pHandle = &huart1;
+  Uart1Ctrl.rxWriteIndex = 0;
+  Uart1Ctrl.rxReadIndex = 0;
+  Uart1Ctrl.dmaRxActive = 0;
+  Uart1Ctrl.dmaTxActive = 0;
+  Uart1Ctrl.pRxBuffer = rxBuffer;
+  Uart1Ctrl.pTxBuffer = txBuffer;
+  Uart1Ctrl.txBufferQueLen = 0;
+
+#ifndef ENABLE_GPIO_V2
+  UART_SetGnssCtrl(&Uart1Ctrl);
+#endif
 }
 
 
@@ -109,9 +118,9 @@
 	HAL_DMA_Abort(&hdma_usart1_tx);
 	HAL_DMA_DeInit(&hdma_usart1_tx);
 	HAL_UART_DeInit(&huart1);
-	dmaRxActive = 0;
-	dmaTxActive = 0;
-	txBufferQueLen = 0;
+	Uart1Ctrl.dmaRxActive = 0;
+	Uart1Ctrl.dmaTxActive = 0;
+	Uart1Ctrl.txBufferQueLen = 0;
 }
 
 void  MX_USART1_DMA_Init()
@@ -156,7 +165,7 @@
   HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
 }
 
-void  UART_MUX_SelectAddress(uint8_t muxAddress)
+void UART_MUX_SelectAddress(uint8_t muxAddress)
 {
 	uint8_t indexstr[4];
 
@@ -166,14 +175,14 @@
 		indexstr[1] = muxAddress;
 		indexstr[2] = 0x0D;
 		indexstr[3] = 0x0A;
-		if(!dmaTxActive)
+		if(!Uart1Ctrl.dmaTxActive)
 		{
 			memcpy(txBuffer, indexstr, 4);
-			dmaTxActive = 0;
+			 Uart1Ctrl.dmaTxActive = 0;
 			if(HAL_OK == HAL_UART_Transmit_DMA(&huart1,txBuffer,4))
 			{
-				dmaTxActive = 1;
-				while(dmaTxActive)
+				 Uart1Ctrl.dmaTxActive = 1;
+				while(Uart1Ctrl.dmaTxActive)
 				{
 					HAL_Delay(1);
 				}
@@ -182,7 +191,7 @@
 		else
 		{
 			memcpy(txBufferQue, indexstr, 4);
-			txBufferQueLen = 4;
+			Uart1Ctrl.txBufferQueLen = 4;
 		}
 	}
 }
@@ -192,18 +201,18 @@
 {
 	uint8_t cmdLength = strlen((char*)cmdString);
 
-	if(dmaTxActive == 0)
+	if(Uart1Ctrl.dmaTxActive == 0)
 	{
 		if(cmdLength < TX_BUF_SIZE)		/* A longer string is an indication for a missing 0 termination */
 		{
-			if(dmaRxActive == 0)
+			if(Uart1Ctrl.dmaRxActive == 0)
 			{
-				UART_StartDMA_Receiption();
+				UART_StartDMA_Receiption(&Uart1Ctrl);
 			}
 			memcpy(txBuffer, cmdString, cmdLength);
 			if(HAL_OK == HAL_UART_Transmit_DMA(&huart1,txBuffer,cmdLength))
 			{
-				dmaTxActive = 1;
+				Uart1Ctrl.dmaTxActive = 1;
 				LastCmdRequestTick = HAL_GetTick();
 			}
 		}
@@ -211,7 +220,7 @@
 	else
 	{
 		memcpy(txBufferQue, cmdString, cmdLength);
-		txBufferQueLen = cmdLength;
+		Uart1Ctrl.txBufferQueLen = cmdLength;
 	}
 }
 
@@ -219,15 +228,18 @@
 {
 	if(len < TX_BUF_SIZE)		/* A longer string is an indication for a missing 0 termination */
 	{
-		if(dmaRxActive == 0)
+		if(pGnssCtrl != NULL)
 		{
-			UART_StartDMA_Receiption();
-		}
-		memcpy(txBuffer, cmd, len);
-		if(HAL_OK == HAL_UART_Transmit_DMA(&huart1,txBuffer,len))
-		{
-			dmaTxActive = 1;
-			LastCmdRequestTick = HAL_GetTick();
+			if(pGnssCtrl->dmaRxActive == 0)
+			{
+				UART_StartDMA_Receiption(pGnssCtrl);
+			}
+			memcpy(pGnssCtrl->pTxBuffer, cmd, len);
+			if(HAL_OK == HAL_UART_Transmit_DMA(pGnssCtrl->pHandle,pGnssCtrl->pTxBuffer,len))
+			{
+				pGnssCtrl->dmaTxActive = 1;
+				LastCmdRequestTick = HAL_GetTick();
+			}
 		}
 	}
 }
@@ -259,15 +271,15 @@
 	*puint64 = result;
 }
 
-void UART_StartDMA_Receiption()
+void UART_StartDMA_Receiption(sUartComCtrl* pUartCtrl)
 {
-	if(dmaRxActive == 0)
+	if(pUartCtrl->dmaRxActive == 0)
 	{
-    	if(((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) || ((isEndIndication(rxWriteIndex)) && (isEndIndication(rxWriteIndex + 1))))	/* start next transfer if we did not catch up with read index */
+    	if(((pUartCtrl->rxWriteIndex / CHUNK_SIZE) != (pUartCtrl->rxReadIndex / CHUNK_SIZE)) || ((UART_isEndIndication(pUartCtrl, pUartCtrl->rxWriteIndex)) && (UART_isEndIndication(pUartCtrl, pUartCtrl->rxWriteIndex + 1))))	/* start next transfer if we did not catch up with read index */
     	{
-			if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+			if(HAL_OK == HAL_UART_Receive_DMA (pUartCtrl->pHandle, &pUartCtrl->pRxBuffer[pUartCtrl->rxWriteIndex], CHUNK_SIZE))
 			{
-				dmaRxActive = 1;
+				pUartCtrl->dmaRxActive = 1;
 			}
     	}
 	}
@@ -282,67 +294,76 @@
 	HAL_NVIC_SetPriority(USART1_IRQn, 1, 3);
 	HAL_NVIC_EnableIRQ(USART1_IRQn);
 
-	UART_clearRxBuffer();
-	rxReadIndex = 0;
-	rxWriteIndex = 0;
-	dmaRxActive = 0;
-	txBufferQueLen = 0;
+	UART_clearRxBuffer(&Uart1Ctrl);
+	Uart1Ctrl.rxReadIndex = 0;
+	Uart1Ctrl.rxWriteIndex = 0;
+	Uart1Ctrl.dmaRxActive = 0;
+	Uart1Ctrl.txBufferQueLen = 0;
 }
 
+void UART_HandleRxComplete(sUartComCtrl* pUartCtrl)
+{
+	pUartCtrl->dmaRxActive = 0;
+	pUartCtrl->rxWriteIndex+=CHUNK_SIZE;
+	if(pUartCtrl->rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+	{
+		pUartCtrl->rxWriteIndex = 0;
+	}
+	UART_StartDMA_Receiption(pUartCtrl);
+}
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
-    if(huart == &huart1)
-    {
-    	dmaRxActive = 0;
-    	rxWriteIndex+=CHUNK_SIZE;
-    	if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-    	{
-    		rxWriteIndex = 0;
-    	}
-		UART_StartDMA_Receiption();
-    }
+	if(huart == &huart1)
+	{
+		UART_HandleRxComplete(&Uart1Ctrl);
+	}
 #ifdef ENABLE_GPIO_V2
-    if(huart == &huart6)
-    {
-    	UART6_RxCpltCallback(huart);
-    }
+	if(huart == &huart6)
+	{
+		UART_HandleRxComplete(&Uart6Ctrl);
+	}
 #endif
 }
+
+void UART_HandleTxComplete(sUartComCtrl* pUartCtrl)
+{
+	pUartCtrl->dmaTxActive = 0;
+	UART_WriteData(pUartCtrl);
+	if(pUartCtrl->txBufferQueLen)
+	{
+		memcpy(pUartCtrl->pTxBuffer, pUartCtrl->pTxQue, pUartCtrl->txBufferQueLen);
+		HAL_UART_Transmit_DMA(pUartCtrl->pHandle,pUartCtrl->pTxBuffer,pUartCtrl->txBufferQueLen);
+		pUartCtrl->dmaTxActive = 1;
+		pUartCtrl->txBufferQueLen = 0;
+	}
+}
 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
 {
 	if(huart == &huart1)
 	{
-		dmaTxActive = 0;
-		UART_WriteData();
-		if(txBufferQueLen)
-		{
-			memcpy(txBuffer, txBufferQue, txBufferQueLen);
-			HAL_UART_Transmit_DMA(&huart1,txBuffer,txBufferQueLen);
-			dmaTxActive = 1;
-			txBufferQueLen = 0;
-		}
+		UART_HandleTxComplete(&Uart1Ctrl);
 	}
 #ifdef ENABLE_GPIO_V2
 	if(huart == &huart6)
 	{
-		UART6_TxCpltCallback(huart);
+		UART_HandleTxComplete(&Uart6Ctrl);
 	}
 #endif
 }
 
-uint8_t isEndIndication(uint8_t index)
+uint8_t UART_isEndIndication(sUartComCtrl* pCtrl, uint8_t index)
 {
 	uint8_t ret = 0;
 	if(index % 2)
 	{
-		if(rxBuffer[index] == BUFFER_NODATA_HIGH)
+		if(pCtrl->pRxBuffer[index] == BUFFER_NODATA_HIGH)
 		{
 			ret = 1;
 		}
 	}
 	else
 	{
-		if(rxBuffer[index] == BUFFER_NODATA_LOW)
+		if(pCtrl->pRxBuffer[index] == BUFFER_NODATA_LOW)
 		{
 			ret = 1;
 		}
@@ -352,35 +373,58 @@
 }
 void UART_ReadData(uint8_t sensorType)
 {
-	uint8_t localRX = rxReadIndex;
-	uint8_t futureIndex = rxReadIndex + 1;
+	uint8_t localRX;
+	uint8_t futureIndex;
 	uint8_t moreData = 0;
 
+	sUartComCtrl* pUartCtrl;
+
+	if(sensorType == SENSOR_GNSS)
+	{
+#ifdef ENABLE_GPIO_V2
+		pUartCtrl = &Uart6Ctrl;
+#else
+		pUartCtrl = &Uart1Ctrl;
+#endif
+	}
+	else
+	{
+		pUartCtrl = &Uart1Ctrl;
+	}
+	localRX = pUartCtrl->rxReadIndex;
+	futureIndex = pUartCtrl->rxReadIndex + 1;
 	if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
 	{
 		futureIndex = 0;
 	}
 
-	if((!isEndIndication(localRX)) || (!isEndIndication(futureIndex)))	do
+	if(!UART_isEndIndication(pUartCtrl, futureIndex))
 	{
-		while((!isEndIndication(localRX)) || (moreData))
+		moreData = 1;
+	}
+	
+	//if((!isEndIndication(pUartCtrl, localRX)) || (!isEndIndication(pUartCtrl,futureIndex)))	do
+	if((!UART_isEndIndication(pUartCtrl, localRX)) || (moreData))
+	do
+	{
+		while((!UART_isEndIndication(pUartCtrl, localRX)) || (moreData))
 		{
 			moreData = 0;
 			switch (sensorType)
 			{
 				case SENSOR_MUX:
-				case SENSOR_DIGO2:	uartO2_ProcessData(rxBuffer[localRX]);
+				case SENSOR_DIGO2:	uartO2_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 					break;
 	#ifdef ENABLE_CO2_SUPPORT
-				case SENSOR_CO2:	uartCo2_ProcessData(rxBuffer[localRX]);
+				case SENSOR_CO2:	uartCo2_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 					break;
 	#endif
-	#ifdef ENABLE_GNSS_SUPPORT
-					case SENSOR_GNSS:	uartGnss_ProcessData(rxBuffer[localRX]);
+	#if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+					case SENSOR_GNSS:	uartGnss_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 							break;
 	#endif
 	#ifdef ENABLE_SENTINEL_MODE
-				case SENSOR_SENTINEL:	uartSentinel_ProcessData(rxBuffer[localRX]);
+				case SENSOR_SENTINEL:	uartSentinel_ProcessData(pUartCtrl->pRxBuffer[localRX]);
 					break;
 	#endif
 				default:
@@ -388,19 +432,19 @@
 			}
 			if(localRX % 2)
 			{
-				rxBuffer[localRX] = BUFFER_NODATA_HIGH;
+				pUartCtrl->pRxBuffer[localRX] = BUFFER_NODATA_HIGH;
 			}
 			else
 			{
-				rxBuffer[localRX] = BUFFER_NODATA_LOW;
+				pUartCtrl->pRxBuffer[localRX] = BUFFER_NODATA_LOW;
 			}
 
 			localRX++;
-			rxReadIndex++;
-			if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+			pUartCtrl->rxReadIndex++;
+			if(pUartCtrl->rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
 			{
 				localRX = 0;
-				rxReadIndex = 0;
+				pUartCtrl->rxReadIndex = 0;
 			}
 			futureIndex++;
 			if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
@@ -408,48 +452,48 @@
 				futureIndex = 0;
 			}
 		}
-		if(!isEndIndication(futureIndex))
+		if(!UART_isEndIndication(pUartCtrl, futureIndex))
 		{
 			moreData = 1;
 		}
 	} while(moreData);
 }
 
-void UART_WriteData(void)
+void UART_WriteData(sUartComCtrl* pUartCtrl)
 {
-	if(huart1.hdmatx->State == HAL_DMA_STATE_READY)
+	if(pUartCtrl->pHandle->hdmatx->State == HAL_DMA_STATE_READY)
 	{
-		huart1.gState = HAL_UART_STATE_READY;
-		dmaTxActive = 0;
+		pUartCtrl->pHandle->gState = HAL_UART_STATE_READY;
+		pUartCtrl->dmaTxActive = 0;
 	}
-	if(huart1.hdmarx->State == HAL_DMA_STATE_READY)
+	if(pUartCtrl->pHandle->hdmarx->State == HAL_DMA_STATE_READY)
 	{
-		huart1.RxState = HAL_UART_STATE_READY;
-		dmaRxActive = 0;
+		pUartCtrl->pHandle->RxState = HAL_UART_STATE_READY;
+		pUartCtrl->dmaRxActive = 0;
 	}
 }
 
 void UART_FlushRxBuffer(void)
 {
-	uint8_t futureIndex = rxReadIndex + 1;
+	uint8_t futureIndex = Uart1Ctrl.rxReadIndex + 1;
 
 	if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
 	{
 		futureIndex = 0;
 	}
-	while((rxBuffer[rxReadIndex] != BUFFER_NODATA_LOW) && (rxBuffer[futureIndex] != BUFFER_NODATA_HIGH))
+	while((rxBuffer[Uart1Ctrl.rxReadIndex] != BUFFER_NODATA_LOW) && (rxBuffer[futureIndex] != BUFFER_NODATA_HIGH))
 	{
-		if(rxReadIndex % 2)
+		if(Uart1Ctrl.rxReadIndex % 2)
 		{
-			rxBuffer[rxReadIndex++] = BUFFER_NODATA_HIGH;
+			rxBuffer[Uart1Ctrl.rxReadIndex++] = BUFFER_NODATA_HIGH;
 		}
 		else
 		{
-			rxBuffer[rxReadIndex++] = BUFFER_NODATA_LOW;
+			rxBuffer[Uart1Ctrl.rxReadIndex++] = BUFFER_NODATA_LOW;
 		}
-		if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+		if(Uart1Ctrl.rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
 		{
-			rxReadIndex = 0;
+			Uart1Ctrl.rxReadIndex = 0;
 		}
 		futureIndex++;
 		if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
--- a/Small_CPU/Src/uartProtocol_Co2.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uartProtocol_Co2.c	Sat Dec 07 21:28:08 2024 +0100
@@ -24,7 +24,6 @@
 #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 receiveStateCO2_t rxState = CO2RX_Ready;
@@ -84,8 +83,8 @@
 	{
 		CO2Connected = 0;
 		externalInterface_SetCO2Scale(0.0);
-		UART_clearRxBuffer();
-		UART_StartDMA_Receiption();
+		UART_clearRxBuffer(&Uart1Ctrl);
+		UART_StartDMA_Receiption(&Uart1Ctrl);
 		localComState = UART_CO2_SETUP;
 	}
 	if(localComState == UART_CO2_SETUP)
@@ -123,7 +122,7 @@
 		else
 		{
 			localComState = UART_CO2_OPERATING;					/* sensor in streaming mode if not connected to mux => operating */
-			UART_StartDMA_Receiption();
+			UART_StartDMA_Receiption(&Uart1Ctrl);
 		}
 	}
 	lastComState = localComState;
--- a/Small_CPU/Src/uartProtocol_GNSS.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uartProtocol_GNSS.c	Sat Dec 07 21:28:08 2024 +0100
@@ -27,7 +27,11 @@
 #include "configuration.h"
 #include "externalInterface.h"
 
-#if defined ENABLE_GNSS || defined ENABLE_GNSS_SUPPORT
+
+#if defined ENABLE_GNSS || defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
+
+static uartGnssStatus_t gnssState = UART_GNSS_INIT;
+static gnssRequest_s activeRequest = {0,0};
 
 static receiveStateGnss_t rxState = GNSSRX_READY;
 static uint8_t GnssConnected = 0;						/* Binary indicator if a sensor is connected or not */
@@ -60,7 +64,16 @@
 }
 
 
-void uartGnss_SendCmd(uint8_t GnssCmd)
+uartGnssStatus_t uartGnss_GetState()
+{
+	return gnssState;
+}
+void uartGnss_SetState(uartGnssStatus_t newState)
+{
+	gnssState = newState;
+}
+
+void UART_Gnss_SendCmd(uint8_t GnssCmd)
 {
 	const uint8_t* pData;
 	uint8_t txLength = 0;
@@ -82,12 +95,16 @@
 		case GNSSCMD_GET_NAV_DATA:	pData = getNavigatorData;
 									txLength = sizeof(getNavigatorData) / sizeof(uint8_t);
 			break;
-
+		case GNSSCMD_GET_NAVSAT_DATA: pData = getNavSat;
+									  txLength = sizeof(getNavSat) / sizeof(uint8_t);
+			break;
 		default:
 			break;
 	}
 	if(txLength != 0)
 	{
+		activeRequest.class = pData[2];
+		activeRequest.id = pData[3];
 		UART_SendCmdUbx(pData, txLength);
 	}
 }
@@ -95,58 +112,88 @@
 void uartGnss_Control(void)
 {
 	static uint32_t warmupTick = 0;
-
-	uint8_t activeSensor = externalInterface_GetActiveUartSensor();
-	uartGnssStatus_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+	static uint8_t dataToggle = 0;
+	uint8_t activeSensor = 0;
+	sUartComCtrl* pUartCtrl = UART_GetGnssCtrl();
+//	uartGnssStatus_t localComState;
 
-	switch (localComState)
+	if(pUartCtrl == &Uart1Ctrl)
 	{
-		case UART_GNSS_INIT:  		localComState = UART_GNSS_WARMUP;
+		activeSensor = externalInterface_GetActiveUartSensor();
+		gnssState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+	}
+
+	switch (gnssState)
+	{
+		case UART_GNSS_INIT:  		gnssState = UART_GNSS_WARMUP;
 									warmupTick =  HAL_GetTick();
-									UART_clearRxBuffer();
+									UART_clearRxBuffer(pUartCtrl);
 				break;
 		case UART_GNSS_WARMUP:		if(time_elapsed_ms(warmupTick,HAL_GetTick()) > 1000)
 									{
-										localComState = UART_GNSS_LOADCONF_0;
+										gnssState = UART_GNSS_LOADCONF_0;
 									}
 				break;
-		case UART_GNSS_LOADCONF_0:	uartGnss_SendCmd(GNSSCMD_LOADCONF_0);
-									localComState = UART_GNSS_LOADCONF_1;
+		case UART_GNSS_LOADCONF_0:	UART_Gnss_SendCmd(GNSSCMD_LOADCONF_0);
+									rxState = GNSSRX_DETECT_ACK_0;
+				break;
+		case UART_GNSS_LOADCONF_1:	UART_Gnss_SendCmd(GNSSCMD_LOADCONF_1);
+									rxState = GNSSRX_DETECT_ACK_0;
+				break;
+		case UART_GNSS_LOADCONF_2:	UART_Gnss_SendCmd(GNSSCMD_LOADCONF_2);
 									rxState = GNSSRX_DETECT_ACK_0;
 				break;
-		case UART_GNSS_LOADCONF_1:	uartGnss_SendCmd(GNSSCMD_LOADCONF_1);
-									localComState = UART_GNSS_LOADCONF_2;
-									rxState = GNSSRX_DETECT_ACK_0;
-				break;
-		case UART_GNSS_LOADCONF_2:	uartGnss_SendCmd(GNSSCMD_LOADCONF_2);
-									localComState = UART_GNSS_IDLE;
-									rxState = GNSSRX_DETECT_ACK_0;
-				break;
-		case UART_GNSS_IDLE:		uartGnss_SendCmd(GNSSCMD_GET_PVT_DATA);
-									localComState = UART_GNSS_GET_PVT;
-									rxState = GNSSRX_DETECT_HEADER_0;
+		case UART_GNSS_IDLE:		if(dataToggle)
+									{
+										UART_Gnss_SendCmd(GNSSCMD_GET_PVT_DATA);
+										gnssState = UART_GNSS_GET_PVT;
+										rxState = GNSSRX_DETECT_HEADER_0;
+										dataToggle = 0;
+									}
+									else
+									{
+										UART_Gnss_SendCmd(GNSSCMD_GET_NAVSAT_DATA);
+										gnssState = UART_GNSS_GET_SAT;
+										rxState = GNSSRX_DETECT_HEADER_0;
+										dataToggle = 1;
+									}
 				break;
 		default:
 				break;
 	}
-
-	externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
+	if(pUartCtrl == &Uart1Ctrl)
+	{
+		externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,gnssState);
+	}
 
 }
 
 void uartGnss_ProcessData(uint8_t data)
 {
-	uint8_t activeSensor = externalInterface_GetActiveUartSensor();
+	static uint16_t rxLength = 0;
+	static uint8_t ck_A = 0;
+	static uint8_t ck_B = 0;
+	static uint8_t ck_A_Ref = 0;
+	static uint8_t ck_B_Ref = 0;
+
 	GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
+	if((rxState >= GNSSRX_DETECT_HEADER_2) && (rxState < GNSSRX_READ_CK_A))
+	{
+		ck_A += data;
+		ck_B += ck_A;
+	}
+
 	switch(rxState)
 	{
 		case GNSSRX_DETECT_ACK_0:
 		case GNSSRX_DETECT_HEADER_0:	if(data == 0xB5)
 										{
 											writeIndex = 0;
-											memset(GNSS_Handle.uartWorkingBuffer,0, sizeof(GNSS_Handle.uartWorkingBuffer));
+											memset(GNSS_Handle.uartWorkingBuffer,0xff, sizeof(GNSS_Handle.uartWorkingBuffer));
 											GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
 											rxState++;
+											ck_A = 0;
+											ck_B = 0;
 										}
 			break;
 		case GNSSRX_DETECT_ACK_1:
@@ -168,8 +215,19 @@
 											rxState = GNSSRX_DETECT_HEADER_0;
 										}
 			break;
-		case GNSSRX_DETECT_ACK_3:		if((data == 0x01) || (data == 0x00))
+		case GNSSRX_DETECT_ACK_3:		if((data == 0x01))
 										{
+											if((gnssState >= UART_GNSS_LOADCONF_0) && (gnssState <= UART_GNSS_LOADCONF_2))
+											{
+												if(gnssState == UART_GNSS_LOADCONF_2)
+												{
+													gnssState = UART_GNSS_IDLE;
+												}
+												else
+												{
+													gnssState++;
+												}
+											}
 											GnssConnected = 1;
 											rxState = GNSSRX_READY;
 										}
@@ -178,7 +236,7 @@
 											rxState = GNSSRX_DETECT_HEADER_0;
 										}
 			break;
-		case GNSSRX_DETECT_HEADER_2:	if(data == 0x01)
+		case GNSSRX_DETECT_HEADER_2:	if(data == activeRequest.class)
 			 	 	 	 	 	 	 	{
 											rxState++;
 			 	 	 	 	 	 	 	}
@@ -187,44 +245,51 @@
 											rxState = GNSSRX_DETECT_HEADER_0;
 										}
 			break;
-		case GNSSRX_DETECT_HEADER_3:
-										switch(data)
+		case GNSSRX_DETECT_HEADER_3:	if(data == activeRequest.id)
+ 	 	 								{
+											rxState = GNSSRX_DETECT_LENGTH_0;
+ 	 	 								}
+										else
 										{
-											case 0x21: rxState = GNSSRX_READ_NAV_DATA;
-														dataToRead = 20;
-												break;
-											case 0x07:	rxState = GNSSRX_READ_PVT_DATA;
-														dataToRead = 92;
-												break;
-											case 0x02:  rxState = GNSSRX_READ_POSLLH_DATA;
-												break;
-											default: 	rxState = GNSSRX_DETECT_HEADER_0;
-												break;
+											rxState = GNSSRX_DETECT_HEADER_0;
 										}
-			break;
-			case GNSSRX_READ_NAV_DATA:
-			case GNSSRX_READ_PVT_DATA:
-			case GNSSRX_READ_POSLLH_DATA:		if(dataToRead > 0)
+				break;
+			case GNSSRX_DETECT_LENGTH_0:	rxLength = GNSS_Handle.uartWorkingBuffer[4];
+											rxState = GNSSRX_DETECT_LENGTH_1;
+				break;
+			case GNSSRX_DETECT_LENGTH_1:    rxLength += (GNSS_Handle.uartWorkingBuffer[5] << 8);
+											rxState = GNSSRX_READ_DATA;
+											dataToRead = rxLength;
+				break;
+			case GNSSRX_READ_DATA:				if(dataToRead > 0)
 												{
 													dataToRead--;
 												}
-												else
+												if(dataToRead == 0)
 												{
-														switch(rxState)
-														{
-															case GNSSRX_READ_NAV_DATA: GNSS_ParseNavigatorData(&GNSS_Handle);
-																break;
-															case GNSSRX_READ_PVT_DATA:	GNSS_ParsePVTData(&GNSS_Handle);
-																break;
-															case GNSSRX_READ_POSLLH_DATA:  GNSS_ParsePOSLLHData(&GNSS_Handle);
-																break;
-															default: 	rxState = GNSSRX_DETECT_HEADER_0;
-																break;
-														}
-														rxState = GNSSRX_DETECT_HEADER_0;
-														externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,UART_GNSS_IDLE);
+													rxState = GNSSRX_READ_CK_A;
 												}
 				break;
+			case GNSSRX_READ_CK_A:				ck_A_Ref = data;
+												rxState++;
+				break;
+			case GNSSRX_READ_CK_B:				ck_B_Ref = data;
+												if((ck_A_Ref == ck_A) && (ck_B_Ref == ck_B))
+												{
+													switch(gnssState)
+													{
+														case UART_GNSS_GET_PVT:GNSS_ParsePVTData(&GNSS_Handle);
+															break;
+														case UART_GNSS_GET_SAT: GNSS_ParseNavSatData(&GNSS_Handle);
+															break;
+														default:
+															break;
+													}
+												}
+												rxState = GNSSRX_DETECT_HEADER_0;
+												gnssState = UART_GNSS_IDLE;
+				break;
+
 		default:	rxState = GNSSRX_READY;
 			break;
 	}
--- a/Small_CPU/Src/uartProtocol_O2.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uartProtocol_O2.c	Sat Dec 07 21:28:08 2024 +0100
@@ -106,7 +106,7 @@
 
 		localComState = UART_O2_CHECK;
 		lastComState = UART_O2_CHECK;
-		UART_clearRxBuffer();
+		UART_clearRxBuffer(&Uart1Ctrl);
 		uartO2_SetupCmd(localComState,cmdString,&cmdLength);
 		UART_SendCmdString(cmdString);
 		rxState = O2RX_CONFIRM;
--- a/Small_CPU/Src/uartProtocol_Sentinel.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uartProtocol_Sentinel.c	Sat Dec 07 21:28:08 2024 +0100
@@ -29,6 +29,8 @@
 static uint8_t SentinelConnected = 0;						/* Binary indicator if a sensor is connected or not */
 static receiveStateSentinel_t rxState = SENTRX_Ready;
 
+extern sUartComCtrl Uart1Ctrl;
+
 void ConvertByteToHexString(uint8_t byte, char* str)
 {
 	uint8_t worker = 0;
@@ -60,7 +62,7 @@
 	if(localComState == UART_SENTINEL_INIT)
 	{
 		SentinelConnected = 0;
-		UART_StartDMA_Receiption();
+		UART_StartDMA_Receiption(&Uart1Ctrl);
 		localComState = UART_SENTINEL_IDLE;
 	}
 	externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
--- a/Small_CPU/Src/uart_Internal.c	Tue Dec 03 20:32:51 2024 +0100
+++ b/Small_CPU/Src/uart_Internal.c	Sat Dec 07 21:28:08 2024 +0100
@@ -28,60 +28,23 @@
 #include <string.h>	/* memset */
 
 
-static uint8_t isEndIndication6(uint8_t index);
-static uartGnssStatus_t gnssState = UART_GNSS_INIT;
-static gnssRequest_s activeRequest = {0,0};
-
 /* Private variables ---------------------------------------------------------*/
 
-
-#define TX_BUF_SIZE				(40u)		/* max length for commands */
-#define CHUNK_SIZE				(50u)		/* the DMA will handle chunk size transfers */
-#define CHUNKS_PER_BUFFER		(3u)
-
 #define REQUEST_INT_SENSOR_MS	(1500)		/* Minimum time interval for cyclic sensor data requests per sensor (UART mux) */
 #define COMMAND_TX_DELAY		(30u)		/* The time the sensor needs to recover from a invalid command request */
 #define TIMEOUT_SENSOR_ANSWER	(300)		/* Time till a request is repeated if no answer was received */
 
-
-static receiveStateGnss_t rxState = GNSSRX_READY;
-static uint8_t GnssConnected = 0;						/* Binary indicator if a sensor is connected or not */
-
-static uint8_t writeIndex = 0;
-
-static uint16_t dataToRead = 0;
-
 DMA_HandleTypeDef  hdma_usart6_rx, hdma_usart6_tx;
 
 uint8_t tx6Buffer[CHUNK_SIZE];							/* tx uses less bytes */
-uint8_t tx6BufferQue[TX_BUF_SIZE];						/* In MUX mode command may be send shortly after each other => allow q 1 entry que */
-uint8_t tx6BufferQueLen;
 
 uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow variations in buffer read time */
 uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow variations in buffer read time */
 
-static uint8_t rx6WriteIndex;							/* Index of the data item which is analysed */
-static uint8_t rx6ReadIndex;								/* Index at which new data is stared */
-
-static uint8_t dmaRx6Active;								/* Indicator if DMA reception needs to be started */
-static uint8_t dmaTx6Active;								/* Indicator if DMA reception needs to be started */
-
+sUartComCtrl Uart6Ctrl;
 
 /* Exported functions --------------------------------------------------------*/
 
-void UART_clearRx6Buffer(void)
-{
-	uint16_t index = 0;
-	do
-	{
-		rxBufferUart6[index++] = BUFFER_NODATA_LOW;
-		rxBufferUart6[index++] = BUFFER_NODATA_HIGH;
-	} while (index < sizeof(rxBufferUart6));
-
-	rx6ReadIndex = 0;
-	rx6WriteIndex = 0;
-}
-
 void GNSS_IO_init() {
 
 	GPIO_InitTypeDef GPIO_InitStruct = { 0 };
@@ -176,364 +139,20 @@
 	huart6.Init.OverSampling = UART_OVERSAMPLING_16;
 	HAL_UART_Init(&huart6);
 
-	UART_clearRx6Buffer();
-	dmaRx6Active = 0;
-	dmaTx6Active = 0;
-	tx6BufferQueLen = 0;
-}
-
-
-
-void UART6_SendCmdUbx(const uint8_t *cmd, uint8_t len)
-{
-	if(len < TX_BUF_SIZE)		/* A longer string is an indication for a missing 0 termination */
-	{
-		if(dmaRx6Active == 0)
-		{
-			UART6_StartDMA_Receiption();
-		}
-		memcpy(tx6Buffer, cmd, len);
-		if(HAL_OK == HAL_UART_Transmit_DMA(&huart6,tx6Buffer,len))
-		{
-			dmaTx6Active = 1;
-		}
-	}
-}
-
-uint8_t isEndIndication6(uint8_t index)
-{
-	uint8_t ret = 0;
-	if(index % 2)
-	{
-		if(rxBufferUart6[index] == BUFFER_NODATA_HIGH)
-		{
-			ret = 1;
-		}
-	}
-	else
-	{
-		if(rxBufferUart6[index] == BUFFER_NODATA_LOW)
-		{
-			ret = 1;
-		}
-	}
-
-	return ret;
-}
-
-void UART6_StartDMA_Receiption()
-{
-	if(dmaRx6Active == 0)
-	{
-    	if(((rx6WriteIndex / CHUNK_SIZE) != (rx6ReadIndex / CHUNK_SIZE)) || ((isEndIndication6(rx6WriteIndex)) && (isEndIndication6(rx6WriteIndex + 1))))	/* start next transfer if we did not catch up with read index */
-    	{
-			if(HAL_OK == HAL_UART_Receive_DMA (&huart6, &rxBufferUart6[rx6WriteIndex], CHUNK_SIZE))
-			{
-				dmaRx6Active = 1;
-			}
-    	}
-	}
-}
-
-
-
-void UART6_RxCpltCallback(UART_HandleTypeDef *huart)
-{
-    if(huart == &huart6)
-    {
-    	dmaRx6Active = 0;
-    	rx6WriteIndex+=CHUNK_SIZE;
-    	if(rx6WriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-    	{
-    		rx6WriteIndex = 0;
-    	}
-		UART6_StartDMA_Receiption();
-    }
-}
-void UART6_TxCpltCallback(UART_HandleTypeDef *huart)
-{
-	if(huart == &huart6)
-	{
-		dmaTx6Active = 0;
-		UART6_WriteData();
-		if(tx6BufferQueLen)
-		{
-			memcpy(tx6Buffer, tx6BufferQue, tx6BufferQueLen);
-			HAL_UART_Transmit_DMA(&huart6,tx6Buffer,tx6BufferQueLen);
-			dmaTx6Active = 1;
-			tx6BufferQueLen = 0;
-		}
-	}
-}
-
-void UART6_ReadData()
-{
-	uint8_t localRX = rx6ReadIndex;
-	uint8_t futureIndex = rx6ReadIndex + 1;
-	uint8_t moreData = 0;
-
-	if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-	{
-		futureIndex = 0;
-	}
-
-	if(!isEndIndication6(futureIndex))
-	{
-		moreData = 1;
-	}
-
-	if((!isEndIndication6(localRX)) || (moreData))
-	do
-	{
-		while((!isEndIndication6(localRX)) || (moreData))
-		{
-			moreData = 0;
-			UART6_Gnss_ProcessData(rxBufferUart6[localRX]);
-
-			if(localRX % 2)
-			{
-				rxBufferUart6[localRX] = BUFFER_NODATA_HIGH;
-			}
-			else
-			{
-				rxBufferUart6[localRX] = BUFFER_NODATA_LOW;
-			}
-
-			localRX++;
-			rx6ReadIndex++;
-			if(rx6ReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-			{
-				localRX = 0;
-				rx6ReadIndex = 0;
-			}
-			futureIndex++;
-			if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
-			{
-				futureIndex = 0;
-			}
-		}
-		if(!isEndIndication6(futureIndex))
-		{
-			moreData = 1;
-		}
-	} while(moreData);
-}
-
-void UART6_WriteData(void)
-{
-	if(huart6.hdmatx->State == HAL_DMA_STATE_READY)
-	{
-		huart6.gState = HAL_UART_STATE_READY;
-		dmaTx6Active = 0;
-	}
-	if(huart6.hdmarx->State == HAL_DMA_STATE_READY)
-	{
-		huart6.RxState = HAL_UART_STATE_READY;
-		dmaRx6Active = 0;
-	}
-}
-
-void UART6_Gnss_SendCmd(uint8_t GnssCmd)
-{
-	const uint8_t* pData;
-	uint8_t txLength = 0;
+	UART_clearRxBuffer(&Uart6Ctrl);
 
-	switch (GnssCmd)
-	{
-		case GNSSCMD_LOADCONF_0:	pData = configUBX;
-									txLength = sizeof(configUBX) / sizeof(uint8_t);
-				break;
-		case GNSSCMD_LOADCONF_1:	pData = setNMEA410;
-									txLength = sizeof(setNMEA410) / sizeof(uint8_t);
-				break;
-		case GNSSCMD_LOADCONF_2:	pData = setGNSS;
-									txLength = sizeof(setGNSS) / sizeof(uint8_t);
-				break;
-		case GNSSCMD_GET_PVT_DATA:	pData = getPVTData;
-									txLength = sizeof(getPVTData) / sizeof(uint8_t);
-			break;
-		case GNSSCMD_GET_NAV_DATA:	pData = getNavigatorData;
-									txLength = sizeof(getNavigatorData) / sizeof(uint8_t);
-			break;
-		case GNSSCMD_GET_NAVSAT_DATA: pData = getNavSat;
-									  txLength = sizeof(getNavSat) / sizeof(uint8_t);
-			break;
-		default:
-			break;
-	}
-	if(txLength != 0)
-	{
-		activeRequest.class = pData[2];
-		activeRequest.id = pData[3];
-		UART6_SendCmdUbx(pData, txLength);
-	}
-}
-
-void UART6_Gnss_Control(void)
-{
-	static uint32_t warmupTick = 0;
-	static uint8_t dataToggle = 0;
-
-	switch (gnssState)
-	{
-		case UART_GNSS_INIT:  		gnssState = UART_GNSS_WARMUP;
-									warmupTick =  HAL_GetTick();
-									UART_clearRxBuffer();
-				break;
-		case UART_GNSS_WARMUP:		if(time_elapsed_ms(warmupTick,HAL_GetTick()) > 1000)
-									{
-										gnssState = UART_GNSS_LOADCONF_0;
-									}
-				break;
-		case UART_GNSS_LOADCONF_0:	UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_0);
-									gnssState = UART_GNSS_LOADCONF_1;
-									rxState = GNSSRX_DETECT_ACK_0;
-				break;
-		case UART_GNSS_LOADCONF_1:	UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_1);
-									gnssState = UART_GNSS_LOADCONF_2;
-									rxState = GNSSRX_DETECT_ACK_0;
-				break;
-		case UART_GNSS_LOADCONF_2:	UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_2);
-									gnssState = UART_GNSS_IDLE;
-									rxState = GNSSRX_DETECT_ACK_0;
-				break;
-		case UART_GNSS_IDLE:		if(dataToggle)
-									{
-										UART6_Gnss_SendCmd(GNSSCMD_GET_PVT_DATA);
-										gnssState = UART_GNSS_GET_PVT;
-										rxState = GNSSRX_DETECT_HEADER_0;
-										dataToggle = 0;
-									}
-									else
-									{
-										UART6_Gnss_SendCmd(GNSSCMD_GET_NAVSAT_DATA);
-										gnssState = UART_GNSS_GET_SAT;
-										rxState = GNSSRX_DETECT_HEADER_0;
-										dataToggle = 1;
-									}
-				break;
-		default:
-				break;
-	}
-}
-
-void UART6_Gnss_ProcessData(uint8_t data)
-{
-	static uint16_t rxLength = 0;
-	static uint8_t ck_A = 0;
-	static uint8_t ck_B = 0;
-	static uint8_t ck_A_Ref = 0;
-	static uint8_t ck_B_Ref = 0;
-
-	GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
-	if((rxState >= GNSSRX_DETECT_HEADER_2) && (rxState < GNSSRX_READ_CK_A))
-	{
-		ck_A += data;
-		ck_B += ck_A;
-	}
+	Uart6Ctrl.pHandle = &huart6;
+	Uart6Ctrl.dmaRxActive = 0;
+	Uart6Ctrl.dmaTxActive = 0;
+	Uart6Ctrl.pRxBuffer = rxBufferUart6;
+	Uart6Ctrl.pTxBuffer = txBufferUart6;
+	Uart6Ctrl.rxReadIndex = 0;
+	Uart6Ctrl.rxWriteIndex = 0;
+	Uart6Ctrl.txBufferQueLen = 0;
 
-	switch(rxState)
-	{
-		case GNSSRX_DETECT_ACK_0:
-		case GNSSRX_DETECT_HEADER_0:	if(data == 0xB5)
-										{
-											writeIndex = 0;
-											memset(GNSS_Handle.uartWorkingBuffer,0xff, sizeof(GNSS_Handle.uartWorkingBuffer));
-											GNSS_Handle.uartWorkingBuffer[writeIndex++] = data;
-											rxState++;
-											ck_A = 0;
-											ck_B = 0;
-										}
-			break;
-		case GNSSRX_DETECT_ACK_1:
-		case GNSSRX_DETECT_HEADER_1:	if(data == 0x62)
-			 	 	 	 	 	 	 	{
-											rxState++;
-			 	 	 	 	 	 	 	}
-										else
-										{
-											rxState = GNSSRX_DETECT_HEADER_0;
-										}
-			break;
-		case GNSSRX_DETECT_ACK_2:		if(data == 0x05)
-										{
-											rxState++;
-										}
-										else
-										{
-											rxState = GNSSRX_DETECT_HEADER_0;
-										}
-			break;
-		case GNSSRX_DETECT_ACK_3:		if((data == 0x01) || (data == 0x00))
-										{
-											GnssConnected = 1;
-											rxState = GNSSRX_READY;
-										}
-										else
-										{
-											rxState = GNSSRX_DETECT_HEADER_0;
-										}
-			break;
-		case GNSSRX_DETECT_HEADER_2:	if(data == activeRequest.class)
-			 	 	 	 	 	 	 	{
-											rxState++;
-			 	 	 	 	 	 	 	}
-										else
-										{
-											rxState = GNSSRX_DETECT_HEADER_0;
-										}
-			break;
-		case GNSSRX_DETECT_HEADER_3:	if(data == activeRequest.id)
- 	 	 								{
-											rxState = GNSSRX_DETECT_LENGTH_0;
- 	 	 								}
-										else
-										{
-											rxState = GNSSRX_DETECT_HEADER_0;
-										}
-				break;
-			case GNSSRX_DETECT_LENGTH_0:	rxLength = GNSS_Handle.uartWorkingBuffer[4];
-											rxState = GNSSRX_DETECT_LENGTH_1;
-				break;
-			case GNSSRX_DETECT_LENGTH_1:    rxLength += (GNSS_Handle.uartWorkingBuffer[5] << 8);
-											rxState = GNSSRX_READ_DATA;
-											dataToRead = rxLength;
-				break;
-			case GNSSRX_READ_DATA:				if(dataToRead > 0)
-												{
-													dataToRead--;
-												}
-												if(dataToRead == 0)
-												{
-													rxState = GNSSRX_READ_CK_A;
-												}
-				break;
-			case GNSSRX_READ_CK_A:				ck_A_Ref = data;
-												rxState++;
-				break;
-			case GNSSRX_READ_CK_B:				ck_B_Ref = data;
-												if((ck_A_Ref == ck_A) && (ck_B_Ref == ck_B))
-												{
-													switch(gnssState)
-													{
-														case UART_GNSS_GET_PVT:GNSS_ParsePVTData(&GNSS_Handle);
-															break;
-														case UART_GNSS_GET_SAT: GNSS_ParseNavSatData(&GNSS_Handle);
-															break;
-														default:
-															break;
-													}
-												}
-												rxState = GNSSRX_DETECT_HEADER_0;
-												gnssState = UART_GNSS_IDLE;
-				break;
-
-		default:	rxState = GNSSRX_READY;
-			break;
-	}
+	UART_SetGnssCtrl(&Uart6Ctrl);
 }
 
-
 void UART6_HandleUART()
 {
 	static uint8_t retryRequest = 0;
@@ -542,10 +161,12 @@
 	static uint8_t timeToTrigger = 0;
 	uint32_t tick =  HAL_GetTick();
 
+	uartGnssStatus_t gnssState = uartGnss_GetState();
+
 		if(gnssState != UART_GNSS_INIT)
 		{
-			UART6_ReadData();
-			UART6_WriteData();
+			UART_ReadData(SENSOR_GNSS);
+			UART_WriteData(&Uart6Ctrl);
 		}
 		if(gnssState == UART_GNSS_INIT)
 		{
@@ -576,13 +197,14 @@
 			if((gnssState == UART_GNSS_GET_SAT) || (gnssState == UART_GNSS_GET_PVT))	/* timeout */
 			{
 				gnssState = UART_GNSS_IDLE;
+				uartGnss_SetState(gnssState);
 			}
 			timeToTrigger = 1;
 		}
 		if((timeToTrigger != 0) && (time_elapsed_ms(TriggerTick,tick) > timeToTrigger))
 		{
 			timeToTrigger = 0;
-			UART6_Gnss_Control();
+			uartGnss_Control();
 		}
 
 }