Mercurial > public > ostc4
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;