diff Small_CPU/Src/uart.c @ 704:f1b40364b0af

Added protocol functions for UART DiveO2 sensor: The code has been modified to support the handling of several protocols (including baud rate changes). The data is requested by polling and passed via DMA into a ringbuffer which is then parsed by a cyclic function call in the main loop. At the moment only the O2 values are forwarded but because the sensor send several types of data within a signle message already more is extracted but yet discarded.
author Ideenmodellierer
date Fri, 28 Oct 2022 20:49:21 +0200
parents fca2bd25e6e2
children 045ff7800501
line wrap: on
line diff
--- a/Small_CPU/Src/uart.c	Fri Oct 28 20:32:24 2022 +0200
+++ b/Small_CPU/Src/uart.c	Fri Oct 28 20:49:21 2022 +0200
@@ -22,6 +22,7 @@
 #include "uart.h"
 #include "externalInterface.h"
 #include "data_exchange.h"
+#include <string.h>	/* memset */
 
 /* Private variables ---------------------------------------------------------*/
 
@@ -37,6 +38,13 @@
 static uint8_t lastCmdIndex;					/* Index of last command which has not been completly received */
 static uint8_t dmaActive;						/* Indicator if DMA receiption needs to be started */
 
+char tmpRxBuf[30];
+uint8_t tmpRxIdx = 0;
+
+static uartO2Status_t Comstatus_O2 = UART_O2_INIT;
+
+static uint32_t DigitalO2ID = 0;
+
 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;
@@ -47,7 +55,16 @@
 /* regular init */	
 
   huart1.Instance = USART1;
-  huart1.Init.BaudRate = 9600;
+
+  if(externalInterface_GetUARTProtocol() == 0x04)
+  {
+	  huart1.Init.BaudRate = 19200;
+	  Comstatus_O2 = UART_O2_INIT;
+  }
+  else
+  {
+	  huart1.Init.BaudRate = 9600;
+  }
   huart1.Init.WordLength = UART_WORDLENGTH_8B;
   huart1.Init.StopBits = UART_STOPBITS_1;
   huart1.Init.Parity = UART_PARITY_NONE;
@@ -57,14 +74,18 @@
 
   HAL_UART_Init(&huart1);
 
+  MX_USART1_DMA_Init();
+
   rxReadIndex = 0;
   lastCmdIndex = 0;
   rxWriteIndex = 0;
   dmaActive = 0;
+  Comstatus_O2 = UART_O2_INIT;
 }
 
 void MX_USART1_UART_DeInit(void)
 {
+	HAL_DMA_Abort(&hdma_usart1_rx);
 	HAL_DMA_DeInit(&hdma_usart1_rx);
 	HAL_UART_DeInit(&huart1);
 }
@@ -356,6 +377,228 @@
 }
 #endif
 
+void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength)
+{
+	switch (O2State)
+	{
+		case UART_O2_CHECK:		*cmdLength = snprintf((char*)cmdString, 10, "#LOGO");
+			break;
+		case UART_O2_REQ_INFO: 	*cmdLength = snprintf((char*)cmdString, 10, "#VERS");
+					break;
+		case UART_O2_REQ_ID: 	*cmdLength = snprintf((char*)cmdString, 10, "#IDNR");
+			break;
+		case UART_O2_REQ_O2: 	*cmdLength = snprintf((char*)cmdString, 10, "#DOXY");
+			break;
+
+		default: *cmdLength = 0;
+			break;
+	}
+	if(*cmdLength != 0)
+	{
+		cmdString[*cmdLength] = 0x0D;
+		*cmdLength = *cmdLength + 1;
+	}
+}
+
+void StringToInt(char *pstr, uint32_t *pInt)
+{
+	uint8_t index = 0;
+	uint32_t result = 0;
+	while((pstr[index] >= '0') && (pstr[index] <= '9'))
+	{
+		result *=10;
+		result += pstr[index] - '0';
+		index++;
+	}
+	*pInt = result;
+}
+
+void HandleUARTDigitalO2(void)
+{
+	static uint32_t lastO2ReqTick = 0;
+
+	static uartO2RxState_t rxState = O2RX_IDLE;
+	static uint32_t lastReceiveTick = 0;
+	static uint8_t lastAlive = 0;
+	static uint8_t curAlive = 0;
+
+	static uint8_t cmdLength = 0;
+	static uint8_t cmdString[10];
+	static uint8_t cmdReadIndex = 0;
+
+	uint32_t tmpO2 = 0;
+	uint32_t tmpData = 0;
+	uint8_t localRX = rxReadIndex;
+	uint32_t tick =  HAL_GetTick();
+
+
+	if(Comstatus_O2 == UART_O2_INIT)
+	{
+		memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
+		lastAlive = 0;
+		curAlive = 0;
+
+		Comstatus_O2 = UART_O2_CHECK;
+		DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+		HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
+
+		rxState = O2RX_CONFIRM;
+		cmdReadIndex = 0;
+		lastO2ReqTick = tick;
+
+		if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+		{
+			dmaActive = 1;
+		}
+	}
+	if(time_elapsed_ms(lastO2ReqTick,tick) > 1000)		/* repeat request once per second */
+	{
+		lastO2ReqTick = tick;
+		if(Comstatus_O2 == UART_O2_IDLE)				/* cyclic request of o2 value */
+		{
+			Comstatus_O2 = UART_O2_REQ_O2;
+			rxState = O2RX_CONFIRM;
+		}
+		DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+
+		HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
+	}
+
+	while((rxBuffer[localRX]!=0))
+	{
+
+		lastReceiveTick = tick;
+		switch(rxState)
+		{
+			case O2RX_CONFIRM:	if(rxBuffer[localRX] == '#')
+								{
+									cmdReadIndex = 0;
+								}
+								if(rxBuffer[localRX] == cmdString[cmdReadIndex])
+							    {
+								cmdReadIndex++;
+								if(cmdReadIndex == cmdLength - 1)
+								{
+									tmpRxIdx = 0;
+									memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf));
+									switch (Comstatus_O2)
+									{
+											case UART_O2_CHECK:	Comstatus_O2 = UART_O2_REQ_INFO;
+																DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength);
+																HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
+												break;
+											case UART_O2_REQ_ID: rxState = O2RX_GETNR;
+												break;
+											case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE;
+												break;
+											case UART_O2_REQ_O2:	rxState = O2RX_GETO2;
+												break;
+											default:	Comstatus_O2 = UART_O2_IDLE;
+														rxState = O2RX_IDLE;
+													break;
+									}
+								}
+						  	}
+				break;
+
+			case O2RX_GETSTATUS:
+			case O2RX_GETTEMP:
+			case O2RX_GETTYPE:
+			case O2RX_GETVERSION:
+			case O2RX_GETCHANNEL:
+			case O2RX_GETSUBSENSORS:
+			case O2RX_GETO2:
+			case O2RX_GETNR:	if(rxBuffer[localRX] != 0x0D)
+								{
+									if(rxBuffer[localRX] != ' ')
+									{
+										tmpRxBuf[tmpRxIdx++] = rxBuffer[localRX];
+									}
+									else
+									{
+										if(tmpRxIdx != 0)
+										{
+											switch(rxState)
+											{
+												case O2RX_GETCHANNEL:	StringToInt(tmpRxBuf,&tmpData);
+																		rxState = O2RX_GETVERSION;
+														break;
+												case O2RX_GETVERSION:	StringToInt(tmpRxBuf,&tmpData);
+																		rxState = O2RX_GETSUBSENSORS;
+														break;
+												case O2RX_GETTYPE: 		StringToInt(tmpRxBuf,&tmpData);
+																		rxState = O2RX_GETCHANNEL;
+														break;
+
+												case O2RX_GETO2: 		StringToInt(tmpRxBuf,&tmpO2);
+																		setExternalInterfaceChannel(0,(float)(tmpO2 / 10000.0));
+																		rxState = O2RX_GETTEMP;
+													break;
+												case O2RX_GETTEMP:		rxState = O2RX_GETSTATUS;
+													break;
+												default:
+													break;
+											}
+											memset((char*) tmpRxBuf, 0, tmpRxIdx);
+											tmpRxIdx = 0;
+										}
+									}
+								}
+								else
+								{
+									switch (rxState)
+									{
+										case O2RX_GETSTATUS:		StringToInt(tmpRxBuf,&tmpData);
+																	Comstatus_O2 = UART_O2_IDLE;
+																	rxState = O2RX_IDLE;
+												break;
+										case O2RX_GETSUBSENSORS:	StringToInt(tmpRxBuf,&tmpData);
+																	Comstatus_O2 = UART_O2_IDLE;
+																	rxState = O2RX_IDLE;
+												break;
+										case  O2RX_GETNR: 			StringToInt((char*)rxBuffer,&DigitalO2ID);
+											/* no break */
+										default:		Comstatus_O2 = UART_O2_IDLE;
+														rxState = O2RX_IDLE;
+											break;
+									}
+								}
+					break;
+			default:				rxState = O2RX_IDLE;
+				break;
+
+		}
+
+		localRX++;
+		rxReadIndex++;
+		if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+		{
+			localRX = 0;
+			rxReadIndex = 0;
+		}
+	}
+
+	if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000)	/* check for communication timeout */
+	{
+		if(curAlive == lastAlive)
+		{
+			setExternalInterfaceChannel(0,0.0);
+			setExternalInterfaceChannel(1,0.0);
+			setExternalInterfaceChannel(2,0.0);
+		}
+		lastAlive = curAlive;
+	}
+
+	if((dmaActive == 0)	&& (externalInterface_isEnabledPower33()))	/* Should never happen in normal operation => restart in case of communication error */
+	{
+		if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+		{
+			dmaActive = 1;
+		}
+	}
+}
+
+
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
     if(huart == &huart1)
@@ -370,6 +613,7 @@
     	{
     		if(externalInterface_isEnabledPower33())
     		{
+    			memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE);
 				if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
 				{
 					dmaActive = 1;