diff Small_CPU/Src/uart.c @ 696:cc542448fb28

Merge
author heinrichsweikamp
date Fri, 19 Aug 2022 11:30:24 +0200
parents fca2bd25e6e2
children f1b40364b0af
line wrap: on
line diff
--- a/Small_CPU/Src/uart.c	Mon Nov 01 12:39:34 2021 +0100
+++ b/Small_CPU/Src/uart.c	Fri Aug 19 11:30:24 2022 +0200
@@ -20,57 +20,370 @@
   */ 
 /* Includes ------------------------------------------------------------------*/
 #include "uart.h"
+#include "externalInterface.h"
+#include "data_exchange.h"
 
 /* Private variables ---------------------------------------------------------*/
 
-UART_HandleTypeDef huart2;
+#define CHUNK_SIZE			(20u)		/* the DMA will handle chunk size transfers */
+#define CHUNKS_PER_BUFFER	(3u)
+UART_HandleTypeDef huart1;
+
+DMA_HandleTypeDef  hdma_usart1_rx;
 
+uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER];		/* The complete buffer has a X * chunk size to allow fariations in buffer read time */
+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 completly received */
+static uint8_t dmaActive;						/* Indicator if DMA receiption needs to be started */
 
+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 --------------------------------------------------------*/
 
-void MX_USART2_UART_Init(void)
+void MX_USART1_UART_Init(void)
 {
-/* pullup special */
-  GPIO_InitTypeDef   GPIO_InitStructure;
-  __GPIOA_CLK_ENABLE();
-  GPIO_InitStructure.Pin = GPIO_PIN_2;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull = GPIO_PULLUP;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
-  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 
+/* regular init */	
+
+  huart1.Instance = USART1;
+  huart1.Init.BaudRate = 9600;
+  huart1.Init.WordLength = UART_WORDLENGTH_8B;
+  huart1.Init.StopBits = UART_STOPBITS_1;
+  huart1.Init.Parity = UART_PARITY_NONE;
+  huart1.Init.Mode = UART_MODE_TX_RX;
+  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
+
+  HAL_UART_Init(&huart1);
+
+  rxReadIndex = 0;
+  lastCmdIndex = 0;
+  rxWriteIndex = 0;
+  dmaActive = 0;
+}
+
+void MX_USART1_UART_DeInit(void)
+{
+	HAL_DMA_DeInit(&hdma_usart1_rx);
+	HAL_UART_DeInit(&huart1);
+}
+
+void  MX_USART1_DMA_Init()
+{
+  /* DMA controller clock enable */
+  __DMA2_CLK_ENABLE();
 
-/* regular init */	
-  huart2.Instance = USART2;
-  huart2.Init.BaudRate = 1200;
-  huart2.Init.WordLength = UART_WORDLENGTH_8B;
-  huart2.Init.StopBits = UART_STOPBITS_1;
-  huart2.Init.Parity = UART_PARITY_NONE;
-  huart2.Init.Mode = UART_MODE_TX_RX;
-  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
-  HAL_UART_Init(&huart2);
+  /* Peripheral DMA init*/
+  hdma_usart1_rx.Instance = DMA2_Stream5;
+  hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
+  hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; //DMA_MEMORY_TO_PERIPH;
+  hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+  hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
+  hdma_usart1_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
+  hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+  hdma_usart1_rx.Init.Mode = DMA_NORMAL;
+  hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
+  hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+  HAL_DMA_Init(&hdma_usart1_rx);
+
+  __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx);
+
+  /* DMA interrupt init */
+  HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
+}
+
+void ConvertByteToHexString(uint8_t byte, char* str)
+{
+	uint8_t worker = 0;
+	uint8_t digit = 0;
+	uint8_t digitCnt = 1;
+
+	worker = byte;
+	while((worker!=0) && (digitCnt != 255))
+	{
+		digit = worker % 16;
+		if( digit < 10)
+		{
+			digit += '0';
+		}
+		else
+		{
+			digit += 'A' - 10;
+		}
+		str[digitCnt--]= digit;
+		worker = worker / 16;
+	}
 }
 
 
-uint8_t UART_ButtonAdjust(uint8_t *array)
+#ifdef ENABLE_CO2_SUPPORT
+void HandleUARTCO2Data(void)
+{
+	uint8_t localRX = rxReadIndex;
+	uint8_t dataType = 0;
+	uint32_t dataValue = 0;
+	static receiveState_t rxState = RX_Ready;
+	static uint32_t lastReceiveTick = 0;
+
+	while(localRX != rxWriteIndex)
+	{
+		lastReceiveTick = HAL_GetTick();
+		if(rxState == RX_Ready)		/* identify data content */
+		{
+			switch(rxBuffer[localRX])
+			{
+				case 'l':
+				case 'D':
+				case 'Z':
+									dataType = rxBuffer[localRX];
+									rxState = RX_Data0;
+									dataValue = 0;
+					break;
+
+				default:			/* unknown or corrupted => ignore */
+					break;
+			}
+		}
+		else if((rxState >= RX_Data0) && (rxState <= RX_Data4))
+		{
+			if((rxBuffer[localRX] >= '0') && (rxBuffer[localRX] <= '9'))
+			{
+				dataValue = dataValue * 10 + (rxBuffer[localRX] - '0');
+				rxState++;
+			}
+		}
+		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;
+					default: break;
+				}
+			}
+			if(rxState != RX_Data0)	/* reset state machine because message in wrong format */
+			{
+				rxState = RX_Ready;
+			}
+		}
+
+		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);
+	}
+
+	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;
+		}
+	}
+}
+#endif
+
+#ifdef ENABLE_SENTINEL_MODE
+void HandleUARTSentinelData(void)
 {
-	uint8_t answer[4];
-	
-	HAL_UART_Transmit(&huart2,array,4,1000);
-	HAL_UART_Receive(&huart2,answer,4,2000);
-	if(	(answer[0] == array[0])
-		&&(answer[1] == array[1])
-		&&(answer[2] == array[2])
-		&&(answer[3] == array[3]))
-	return 1;
-	else
-	return 0;
+	uint8_t localRX = rxReadIndex;
+	static uint8_t dataType = 0;
+	static uint32_t dataValue[3];
+	static uint8_t dataValueIdx = 0;
+	static receiveState_t rxState = RX_Ready;
+	static uint32_t lastReceiveTick = 0;
+	static uint8_t lastAlive = 0;
+	static uint8_t curAlive = 0;
+	static uint8_t checksum = 0;
+	char checksum_str[]="00";
+
+	while(localRX != rxWriteIndex)
+	{
+		lastReceiveTick = HAL_GetTick();
+
+		switch(rxState)
+		{
+			case RX_Ready:	if((rxBuffer[localRX] >= 'a') && (rxBuffer[localRX] <= 'z'))
+							{
+								rxState = RX_DetectStart;
+								curAlive = rxBuffer[localRX];
+								checksum = 0;
+							}
+					break;
+
+			case RX_DetectStart: 	checksum += rxBuffer[localRX];
+									if(rxBuffer[localRX] == '1')
+								 	{
+								 		rxState = RX_SelectData;
+								 		dataType = 0xFF;
+
+								 	}
+									else
+									{
+										rxState = RX_Ready;
+									}
+					break;
+
+			case RX_SelectData:		checksum += rxBuffer[localRX];
+									switch(rxBuffer[localRX])
+									{
+										case 'T':	dataType = rxBuffer[localRX];
+											break;
+										case '0': 	if(dataType != 0xff)
+													{
+														rxState = RX_Data0;
+														dataValueIdx = 0;
+														dataValue[0] = 0;
+
+													}
+													else
+													{
+														rxState = RX_Ready;
+													}
+											break;
+										default:	rxState = RX_Ready;
+									}
+					break;
+
+			case RX_Data0:
+			case RX_Data1:
+			case RX_Data2:
+			case RX_Data4:
+			case RX_Data5:
+			case RX_Data6:
+			case RX_Data8:
+			case RX_Data9:
+			case RX_Data10: checksum += rxBuffer[localRX];
+							if((rxBuffer[localRX] >= '0') && (rxBuffer[localRX] <= '9'))
+							{
+								dataValue[dataValueIdx] = dataValue[dataValueIdx] * 10 + (rxBuffer[localRX] - '0');
+								rxState++;
+							}
+							else
+							{
+								rxState = RX_Ready;
+							}
+					break;
+
+			case RX_Data3:
+			case RX_Data7:	checksum += rxBuffer[localRX];
+							if(rxBuffer[localRX] == '0')
+							{
+								rxState++;
+								dataValueIdx++;
+								dataValue[dataValueIdx] = 0;
+							}
+							else
+							{
+								rxState = RX_Ready;
+							}
+					break;
+			case RX_Data11: rxState = RX_DataComplete;
+							ConvertByteToHexString(checksum,checksum_str);
+							if(rxBuffer[localRX] == checksum_str[0])
+							{
+								rxState = RX_DataComplete;
+							}
+							else
+							{
+								rxState = RX_Ready;
+							}
+
+				break;
+
+			case RX_DataComplete:	if(rxBuffer[localRX] == checksum_str[1])
+									{
+										setExternalInterfaceChannel(0,(float)(dataValue[0] / 10.0));
+										setExternalInterfaceChannel(1,(float)(dataValue[1] / 10.0));
+										setExternalInterfaceChannel(2,(float)(dataValue[2] / 10.0));
+									}
+									rxState = RX_Ready;
+				break;
+
+
+			default:				rxState = RX_Ready;
+				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;
+		}
+	}
 }
+#endif
 
-void MX_USART2_UART_DeInit(void)
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
-	HAL_UART_DeInit(&huart2);
+    if(huart == &huart1)
+    {
+    	dmaActive = 0;
+    	rxWriteIndex+=CHUNK_SIZE;
+    	if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
+    	{
+    		rxWriteIndex = 0;
+    	}
+    	if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE))	/* start next transfer if we did not catch up with read index */
+    	{
+    		if(externalInterface_isEnabledPower33())
+    		{
+				if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
+				{
+					dmaActive = 1;
+				}
+    		}
+    	}
+    }
 }
 
 
+
+
+
+
+
+
 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/