# HG changeset patch # User Ideenmodellierer # Date 1705351458 -3600 # Node ID c3dd461ca3f9dd922f3d0d96fae2f05d4c108d46 # Parent 70092f552f5ad2103e0c3d7596fd286674ee4ec3 Migrated Sentinel protocol to new UART structure: The Sentinel protocol had not been migrated to the new UART structure which was introduced with the introduction of the UART MUX. The Sentinel is now supported by autodetection again (development version only) diff -r 70092f552f5a -r c3dd461ca3f9 Common/Inc/data_central.h --- a/Common/Inc/data_central.h Sun Jan 07 21:25:34 2024 +0100 +++ b/Common/Inc/data_central.h Mon Jan 15 21:44:18 2024 +0100 @@ -448,6 +448,7 @@ SENSOR_DIGO2, SENSOR_DIGO2M, SENSOR_SENTINEL, + SENSOR_SENTINELM, SENSOR_TYPE_O2_END, SENSOR_CO2, SENSOR_CO2M, diff -r 70092f552f5a -r c3dd461ca3f9 Discovery/Src/data_exchange_main.c --- a/Discovery/Src/data_exchange_main.c Sun Jan 07 21:25:34 2024 +0100 +++ b/Discovery/Src/data_exchange_main.c Mon Jan 15 21:44:18 2024 +0100 @@ -431,7 +431,7 @@ #ifdef ENABLE_SENTINEL_MODE if(SensorActive[SENSOR_SENTINEL]) { - externalInterface_Cmd |= EXT_INTERFACE_33V_ON | EXT_INTERFACE_UART_SENTINEL; + externalInterface_Cmd |= EXT_INTERFACE_33V_ON; externalInterface_Cmd &= (~EXT_INTERFACE_ADC_ON); } #endif diff -r 70092f552f5a -r c3dd461ca3f9 Discovery/Src/tMenuEditHardware.c --- a/Discovery/Src/tMenuEditHardware.c Sun Jan 07 21:25:34 2024 +0100 +++ b/Discovery/Src/tMenuEditHardware.c Mon Jan 15 21:44:18 2024 +0100 @@ -419,7 +419,8 @@ case SENSOR_CO2M: pSettings->co2_sensor_active = 1; break; #ifdef ENABLE_SENTINEL_MODE - case SENSOR_SENTINEL: pSettings->ppo2sensors_source = O2_SENSOR_SOURCE_SENTINEL; + case SENSOR_SENTINEL: + case SENSOR_SENTINELM: pSettings->ppo2sensors_source = O2_SENSOR_SOURCE_SENTINEL; break; #endif default: @@ -465,7 +466,8 @@ case SENSOR_CO2M: strSensorId[3] = 'C'; strSensorId[4] = 'O'; break; - case SENSOR_SENTINEL: strSensorId[3] = 'S'; + case SENSOR_SENTINEL: + case SENSOR_SENTINELM: strSensorId[3] = 'S'; strSensorId[4] = 'e'; break; default: diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Inc/uartProtocol_Co2.h --- a/Small_CPU/Inc/uartProtocol_Co2.h Sun Jan 07 21:25:34 2024 +0100 +++ b/Small_CPU/Inc/uartProtocol_Co2.h Mon Jan 15 21:44:18 2024 +0100 @@ -43,24 +43,24 @@ 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; + CO2RX_Ready= 0, /* Initial state */ + CO2RX_DetectStart, /* validate start byte */ + CO2RX_SelectData, /* Data contained in this frame */ + CO2RX_Data0, /* Process incoming data */ + CO2RX_Data1, + CO2RX_Data2, + CO2RX_Data3, + CO2RX_Data4, + CO2RX_Data5, + CO2RX_Data6, + CO2RX_Data7, + CO2RX_Data8, + CO2RX_Data9, + CO2RX_Data10, + CO2RX_Data11, + CO2RX_Data12, + CO2RX_DataComplete + } receiveStateCO2_t; typedef enum diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Inc/uartProtocol_Sentinel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Small_CPU/Inc/uartProtocol_Sentinel.h Mon Jan 15 21:44:18 2024 +0100 @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * @file uartProtocol_Sentinel.h + * @author heinrichs weikamp gmbh + * @version V0.0.1 + * @date 15-Jan-2024 + * @brief Interface functionality read data from Sentinel rebreather + * + @verbatim + ============================================================================== + ##### How to use ##### + ============================================================================== + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 heinrichs weikamp

+ * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef UART_PROTOCOL_SENTINEL_H +#define UART_PROTOCOL_SENTINEL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "configuration.h" +#include "stm32f4xx_hal.h" + + typedef enum + { + UART_SENTINEL_INIT = 0, /* Default Status for every sensor type */ + UART_SENTINEL_IDLE, /* sensor detected and no communication pending */ + UART_SENTINEL_ERROR, + UART_SENTINEL_OPERATING, /* normal operation */ + } uartSentinelStatus_t; + + typedef enum + { + SENTRX_Ready= 0, /* Initial state */ + SENTRX_DetectStart, /* validate start byte */ + SENTRX_SelectData, /* Data contained in this frame */ + SENTRX_Data0, /* Process incoming data */ + SENTRX_Data1, + SENTRX_Data2, + SENTRX_Data3, + SENTRX_Data4, + SENTRX_Data5, + SENTRX_Data6, + SENTRX_Data7, + SENTRX_Data8, + SENTRX_Data9, + SENTRX_Data10, + SENTRX_Data11, + SENTRX_Data12, + SENTRX_DataComplete + } receiveStateSentinel_t; + + +void uartSentinel_Control(void); +void uartSentinel_ProcessData(uint8_t data); +uint8_t uartSentinel_isSensorConnected(); + +#endif /* UART_PROTOCOL_SENTINEL_H */ diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Src/externalInterface.c --- a/Small_CPU/Src/externalInterface.c Sun Jan 07 21:25:34 2024 +0100 +++ b/Small_CPU/Src/externalInterface.c Mon Jan 15 21:44:18 2024 +0100 @@ -34,6 +34,7 @@ #include "pressure.h" #include "uartProtocol_O2.h" #include "uartProtocol_Co2.h" +#include "uartProtocol_Sentinel.h" extern SGlobal global; extern UART_HandleTypeDef huart1; @@ -599,6 +600,16 @@ } } } +#ifdef ENABLE_SENTINEL_MODE + if(pMap[EXT_INTERFACE_MUX_OFFSET] == SENSOR_SENTINEL) + { + for(index2 = 0; index2 < MAX_ADC_CHANNEL; index2++) + { + pMap[index2] = SENSOR_SENTINELM; /* store a mirror instance needed for visualization */ + Mux2ADCMap[index2] = index2 + EXT_INTERFACE_MUX_OFFSET; + } + } +#endif } uint8_t* externalInterface_GetSensorMapPointer(uint8_t finalMap) @@ -789,26 +800,34 @@ } else { +#ifdef ENABLE_SENTINEL_MODE + externalAutoDetect = DETECTION_SENTINEL; +#else externalAutoDetect = DETECTION_DONE; +#endif } #endif #ifdef ENABLE_SENTINEL_MODE if(externalAutoDetect == DETECTION_SENTINEL) { + externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET] = UART_COMMON_INIT; + uartO2_SetChannel(0); + activeUartChannel = 0; + tmpSensorMap[EXT_INTERFACE_MUX_OFFSET] = SENSOR_SENTINEL; externalInterface_SwitchUART(EXT_INTERFACE_UART_SENTINEL); + externalInterface_CheckBaudrate(SENSOR_SENTINEL); UART_StartDMA_Receiption(); } break; case DETECTION_SENTINEL: case DETECTION_SENTINEL2: - if(UART_isSentinelConnected()) + if(uartSentinel_isSensorConnected()) { - for(index = 0; index < 3; index++) /* Sentinel is occupiing all sensor slots */ + for(index = EXT_INTERFACE_MUX_OFFSET; index < EXT_INTERFACE_MUX_OFFSET+3; index++) { - tmpSensorMap[index] = SENSOR_SENTINEL; + foundSensorMap[index] = SENSOR_SENTINEL; } - sensorIndex = 3; } externalAutoDetect++; #endif @@ -829,6 +848,14 @@ { cntUARTSensor++; } +#ifdef ENABLE_SENTINEL_MODE + if(foundSensorMap[index] == SENSOR_SENTINEL) /* The Sentinel has a fixed setup */ + { + cntSensor = 3; + cntUARTSensor = 1; + break; + } +#endif } externalInface_MapUartToLegacyADC(foundSensorMap); externalInterfaceMuxReqIntervall = 0xFFFF; @@ -941,6 +968,7 @@ switch(sensorType) { + case SENSOR_SENTINEL: case SENSOR_CO2: newBaudrate = 9600; break; case SENSOR_DIGO2: @@ -976,6 +1004,8 @@ switch(pmap[activeUartChannel + EXT_INTERFACE_MUX_OFFSET]) { + case SENSOR_SENTINEL: externalInterface_CheckBaudrate(SENSOR_SENTINEL); + break; case SENSOR_CO2: externalInterface_CheckBaudrate(SENSOR_CO2); break; default: @@ -1067,6 +1097,10 @@ case SENSOR_CO2: uartCo2_Control(); break; #endif +#ifdef ENABLE_SENTINEL_MODE + case SENSOR_SENTINEL: uartSentinel_Control(); + break; +#endif default: break; } diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Src/uart.c --- a/Small_CPU/Src/uart.c Sun Jan 07 21:25:34 2024 +0100 +++ b/Small_CPU/Src/uart.c Mon Jan 15 21:44:18 2024 +0100 @@ -22,6 +22,7 @@ #include "uart.h" #include "uartProtocol_O2.h" #include "uartProtocol_Co2.h" +#include "uartProtocol_Sentinel.h" #include "externalInterface.h" #include "data_exchange.h" #include /* memset */ @@ -44,9 +45,6 @@ static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */ -static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */ - - /* Exported functions --------------------------------------------------------*/ @@ -72,9 +70,6 @@ lastCmdIndex = 0; rxWriteIndex = 0; dmaActive = 0; - - SentinelConnected = 0; - } void MX_USART1_UART_DeInit(void) @@ -166,28 +161,6 @@ } *puint64 = result; } -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; - } -} void UART_StartDMA_Receiption() { @@ -223,164 +196,6 @@ } } -#ifdef ENABLE_SENTINEL_MODE -void UART_HandleSentinelData(void) -{ - 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; - static char checksum_str[]="00"; - - while((rxBuffer[localRX]!=0)) - { - 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)); - SentinelConnected = 1; - } - 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); - SentinelConnected = 0; - } - lastAlive = curAlive; - } - - if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ - { - UART_StartDMA_Receiption(); - } -} -#endif - - - -uint8_t UART_isSentinelConnected() -{ - return SentinelConnected; -} - void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart == &huart1) @@ -413,6 +228,10 @@ case SENSOR_CO2: uartCo2_ProcessData(rxBuffer[localRX]); break; #endif +#ifdef ENABLE_SENTINEL_MODE + case SENSOR_SENTINEL: uartSentinel_ProcessData(rxBuffer[localRX]); + break; +#endif default: break; } diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Src/uartProtocol_Co2.c --- a/Small_CPU/Src/uartProtocol_Co2.c Sun Jan 07 21:25:34 2024 +0100 +++ b/Small_CPU/Src/uartProtocol_Co2.c Mon Jan 15 21:44:18 2024 +0100 @@ -27,7 +27,7 @@ #ifdef ENABLE_CO2_SUPPORT static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */ -static receiveState_t rxState = RX_Ready; +static receiveStateCO2_t rxState = CO2RX_Ready; @@ -137,7 +137,7 @@ uint8_t activeSensor = externalInterface_GetActiveUartSensor(); uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET); - if(rxState == RX_Ready) /* identify data content */ + if(rxState == CO2RX_Ready) /* identify data content */ { switch(data) { @@ -146,7 +146,7 @@ case 'D': case 'Z': case '.': dataType = data; - rxState = RX_Data0; + rxState = CO2RX_Data0; dataValue = 0; break; case '?': localComState = UART_CO2_ERROR; @@ -157,26 +157,26 @@ } else if((data >= '0') && (data <= '9')) { - if((rxState >= RX_Data0) && (rxState <= RX_Data4)) + if((rxState >= CO2RX_Data0) && (rxState <= CO2RX_Data4)) { dataValue = dataValue * 10 + (data - '0'); rxState++; - if(rxState == RX_Data5) + if(rxState == CO2RX_Data5) { - rxState = RX_DataComplete; + rxState = CO2RX_DataComplete; } } else /* protocol error data has max 5 digits */ { - if(rxState != RX_DataComplete) /* commands will not answer with number values */ + if(rxState != CO2RX_DataComplete) /* commands will not answer with number values */ { - rxState = RX_Ready; + rxState = CO2RX_Ready; } } } if((data == ' ') || (data == '\n')) /* Abort data detection */ { - if(rxState == RX_DataComplete) + if(rxState == CO2RX_DataComplete) { CO2Connected = 1; if(localComState == UART_CO2_SETUP) @@ -204,13 +204,13 @@ break; case '.': externalInterface_SetCO2Scale(dataValue); break; - default: rxState = RX_Ready; + default: rxState = CO2RX_Ready; break; } } - if(rxState != RX_Data0) /* reset state machine because message in wrong format */ + if(rxState != CO2RX_Data0) /* reset state machine because message in wrong format */ { - rxState = RX_Ready; + rxState = CO2RX_Ready; } } externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState); diff -r 70092f552f5a -r c3dd461ca3f9 Small_CPU/Src/uartProtocol_Sentinel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Small_CPU/Src/uartProtocol_Sentinel.c Mon Jan 15 21:44:18 2024 +0100 @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file uartProtocol_Co2.c + * @author heinrichs weikamp gmbh + * @version V0.0.1 + * @date 15-Jan-2024 + * @brief Interface functionality to read data from Sentinel rebreather + * + @verbatim + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2024 heinrichs weikamp

+ * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include +#include +#include "uart.h" +#include "externalInterface.h" + + +#ifdef ENABLE_SENTINEL_MODE +static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */ +static receiveStateSentinel_t rxState = SENTRX_Ready; + +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; + } +} + +void uartSentinel_Control(void) +{ + uint8_t activeSensor = externalInterface_GetActiveUartSensor(); + uartSentinelStatus_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET); + + if(localComState == UART_SENTINEL_INIT) + { + SentinelConnected = 0; + UART_StartDMA_Receiption(); + localComState = UART_SENTINEL_IDLE; + } + externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState); +} + +void uartSentinel_ProcessData(uint8_t data) +{ + static uint8_t dataType = 0; + static uint32_t dataValue[3]; + static uint8_t dataValueIdx = 0; + + static uint8_t lastAlive = 0; + static uint8_t curAlive = 0; + static uint8_t checksum = 0; + static char checksum_str[]="00"; + + uint8_t activeSensor = externalInterface_GetActiveUartSensor(); + uartSentinelStatus_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET); + + switch(rxState) + { + case SENTRX_Ready: if((data >= 'a') && (data <= 'z')) + { + rxState = SENTRX_DetectStart; + curAlive = data; + checksum = 0; + } + break; + + case SENTRX_DetectStart: checksum += data; + if(data == '1') + { + rxState = SENTRX_SelectData; + dataType = 0xFF; + + } + else + { + rxState = SENTRX_Ready; + } + break; + + case SENTRX_SelectData: checksum += data; + switch(data) + { + case 'T': dataType = data; + break; + case '0': if(dataType != 0xff) + { + rxState = SENTRX_Data0; + dataValueIdx = 0; + dataValue[0] = 0; + + } + else + { + rxState = SENTRX_Ready; + } + break; + default: rxState = SENTRX_Ready; + } + break; + + case SENTRX_Data0: + case SENTRX_Data1: + case SENTRX_Data2: + case SENTRX_Data4: + case SENTRX_Data5: + case SENTRX_Data6: + case SENTRX_Data8: + case SENTRX_Data9: + case SENTRX_Data10: checksum += data; + if((data >= '0') && (data <= '9')) + { + dataValue[dataValueIdx] = dataValue[dataValueIdx] * 10 + (data - '0'); + rxState++; + } + else + { + rxState = SENTRX_Ready; + } + break; + + case SENTRX_Data3: + case SENTRX_Data7: checksum += data; + if(data == '0') + { + rxState++; + dataValueIdx++; + dataValue[dataValueIdx] = 0; + } + else + { + rxState = SENTRX_Ready; + } + break; + case SENTRX_Data11: rxState = SENTRX_DataComplete; + ConvertByteToHexString(checksum,checksum_str); + if(data == checksum_str[0]) + { + rxState = SENTRX_DataComplete; + } + else + { + rxState = SENTRX_Ready; + } + + break; + + case SENTRX_DataComplete: if(data == checksum_str[1]) + { + setExternalInterfaceChannel(0,(float)(dataValue[0] / 10.0)); + setExternalInterfaceChannel(1,(float)(dataValue[1] / 10.0)); + setExternalInterfaceChannel(2,(float)(dataValue[2] / 10.0)); + SentinelConnected = 1; + lastAlive = curAlive; + localComState = UART_SENTINEL_OPERATING; + } + rxState = SENTRX_Ready; + break; + + + default: rxState = SENTRX_Ready; + break; + + } + externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState); +} + +uint8_t uartSentinel_isSensorConnected() +{ + return SentinelConnected; +} + +#endif +