# 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 + * + *

© COPYRIGHT(c) 2014 heinrichs weikamp

+ * + ****************************************************************************** + */ + +/* 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 /* 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 + * + *

© COPYRIGHT(c) 2023 heinrichs weikamp

+ * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include +#include +#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);