# HG changeset patch
# User Ideenmodellierer
# Date 1772468545 -3600
# Node ID bd8ab302ef4af0f7d7e446fdfd111c5d455e857a
# Parent c87753e73eb892c53a5ffa82e5373eac546b56a0
Added uart support for HUD:
the protocol implementation for the HUD has been added. It may be activated by the compile switch ENABLE_HUD_SUPPORT. Because the HUD will not mapped to the three classic o2 value display slots, the sensor data structure has been increased to the max number of devices => all devices may now raise device specific data.
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Inc/externalInterface.h
--- a/Small_CPU/Inc/externalInterface.h Sun Feb 22 21:23:57 2026 +0100
+++ b/Small_CPU/Inc/externalInterface.h Mon Mar 02 17:22:25 2026 +0100
@@ -82,6 +82,12 @@
DETECTION_SENTINEL, /* check UART channel for connected Sentinel */
DETECTION_SENTINEL2,
#endif
+#ifdef ENABLE_HUD_SUPPORT
+ DETECTION_HUD_0,
+ DETECTION_HUD_1,
+ DETECTION_HUD_2,
+ DETECTION_HUD_3,
+#endif
DETECTION_DONE
} externalInterfaceAutoDetect_t;
@@ -111,6 +117,8 @@
uint16_t externalInterface_GetCO2SignalStrength(void);
void externalInterface_SetBottlePressure(uint8_t bottle, uint8_t bar);
uint8_t externalInterface_GetBottlePressure(uint8_t bottle);
+void externalInterface_GetHUDSequence(uint8_t* pSequence, uint8_t* brightness);
+void externalInterface_SetHUDSequence(uint8_t* pSequence, uint8_t brightness);
uint8_t externalInterface_GetSensorData(uint8_t sensorId, uint8_t* pDataStruct);
void externalInterface_SetSensorData(uint8_t sensorId, uint8_t* pDataStruct);
void externalInface_SetSensorMap(uint8_t* pMap);
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Inc/uart.h
--- a/Small_CPU/Inc/uart.h Sun Feb 22 21:23:57 2026 +0100
+++ b/Small_CPU/Inc/uart.h Mon Mar 02 17:22:25 2026 +0100
@@ -74,6 +74,9 @@
#ifdef ENABLE_SENTINEL_MODE
void UART_HandleSentinelData(void);
#endif
+#ifdef ENABLE_HUD_SUPPORT
+void UART_HandleHUDData(void);
+#endif
void UART_SetGnssCtrl(sUartComCtrl* pTarget);
sUartComCtrl* UART_GetGnssCtrl();
void UART_clearRxBuffer(sUartComCtrl* pUartCtrl);
@@ -81,6 +84,7 @@
uint8_t UART_isSentinelConnected();
void UART_setTargetChannel(uint8_t channel);
void UART_MUX_SelectAddress(uint8_t muxAddress);
+void UART_SendCmdRaw(const uint8_t *cmd, uint8_t cmdLength);
void UART_SendCmdString(uint8_t *cmdString);
void UART_SendCmdUbx(const uint8_t *cmd, uint8_t len);
void UART_ReadData(uint8_t sensorType, uint8_t flush);
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Inc/uartProtocol_HUD.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Inc/uartProtocol_HUD.h Mon Mar 02 17:22:25 2026 +0100
@@ -0,0 +1,77 @@
+/**
+ ******************************************************************************
+ * @file uartProtocol_HUD.h
+ * @author heinrichs weikamp gmbh
+ * @version V0.0.1
+ * @date 24-Feb-2026
+ * @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_HUD_H
+#define UART_PROTOCOL_HUD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "configuration.h"
+#include "stm32f4xx_hal.h"
+
+
+#define HUD_INFO_DATA_LENGTH (24u) /* expected number of received info data */
+#define HUD_MAX_CMD_LENGTH (32u) /* max length for a command sequence */
+
+#define HUD_CMD_BYTE_START (0xAA) /* Start byte */
+#define HUD_CMD_BYTE_INFO (0x10) /* Request HUD info */
+#define HUD_CMD_BYTE_UPDATE (0x20) /* Update LED sequence command */
+#define HUD_CMD_BYTE_STOP (0x30) /* Stip LED sequence execution */
+
+ typedef enum
+ {
+ UART_HUD_INIT = 0, /* Default Status for every sensor type */
+ UART_HUD_IDLE, /* sensor detected and no communication pending */
+ UART_HUD_ERROR,
+ UART_HUD_SETUP = 10, /* collecting data */
+ UART_HUD_UPDATE, /* update the HUD status LEDs */
+ UART_HUD_ABORT, /* abort status sequence */
+ } uartHUDStatus_t;
+
+ typedef enum
+ {
+ HUDRX_Ready= 0, /* Initial state */
+ HUDRX_DetectStart, /* validate start byte */
+ HUDRX_RXData,
+ HUDRX_CheckSum_L,
+ HUDRX_CheckSum_H,
+ HUDRX_DataComplete
+ } receiveStateHUD_t;
+
+
+ typedef enum
+ {
+ HUDCMD_GETINFO = 0, /* Get HUD info */
+ HUDCMD_UPDATE, /* Update LED sequence */
+ HUDCMD_ABORTSEQ /* Abort LED sequence */
+ } hudSensorCmd_t;
+
+
+void uartHUD_Control(void);
+void uartHUD_ProcessData(uint8_t data);
+void uartHUD_SendCmd(uint8_t HUDCmd);
+uint8_t uartHUD_isSensorConnected();
+
+#endif /* UART_PROTOCOL_HUD_H */
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Src/externalInterface.c
--- a/Small_CPU/Src/externalInterface.c Sun Feb 22 21:23:57 2026 +0100
+++ b/Small_CPU/Src/externalInterface.c Mon Mar 02 17:22:25 2026 +0100
@@ -36,6 +36,7 @@
#include "uartProtocol_Co2.h"
#include "uartProtocol_Sentinel.h"
#include "uartProtocol_GNSS.h"
+#include "uartProtocol_HUD.h"
extern SGlobal global;
extern UART_HandleTypeDef huart1;
@@ -85,9 +86,12 @@
static float externalCO2Scale = 0.0;
static uint8_t externalBottleBar[PRESSURE_BOTTLE_CNT] = {0,0};
+static uint8_t externalHUDBrightness = 0;
+static uint8_t externalHUDSequence[EXT_INTERFACE_HUD_LED_MAX];
+
static uint8_t lastSensorDataId = 0;
-static SSensorDataDiveO2 sensorDataDiveO2[EXT_INTERFACE_SENSOR_CNT];
+static uint8_t sensorData[EXT_INTERFACE_SENSOR_CNT][EXTIF_SENSOR_INFO_SIZE];
static externalInterfaceAutoDetect_t externalAutoDetect = DETECTION_OFF;
static externalInterfaceSensorType SensorMap[EXT_INTERFACE_SENSOR_CNT] ={ SENSOR_OPTIC, SENSOR_OPTIC, SENSOR_OPTIC, SENSOR_NONE, SENSOR_NONE};
static externalInterfaceSensorType tmpSensorMap[EXT_INTERFACE_SENSOR_CNT];
@@ -399,39 +403,12 @@
void externalInterface_SwitchUART(uint8_t protocol)
{
- switch(protocol)
+ lastSensorDataId = 0;
+ externalUART_Protocol = protocol;
+ MX_USART1_UART_DeInit();
+ if( protocol != EXT_INTERFACE_UART_OFF)
{
- case EXT_INTERFACE_UART_OFF:
- case EXT_INTERFACE_UART_CO2:
- case EXT_INTERFACE_UART_O2:
- case EXT_INTERFACE_UART_SENTINEL:
- case EXT_INTERFACE_UART_GNSS:
- if((externalAutoDetect <= DETECTION_START)
- || ((protocol == EXT_INTERFACE_UART_O2) && (externalAutoDetect >= DETECTION_UARTMUX) && (externalAutoDetect <= DETECTION_DIGO2_3))
-
-#ifdef ENABLE_CO2_SUPPORT
- || ((externalAutoDetect >= DETECTION_CO2_0) && (externalAutoDetect <= DETECTION_CO2_3))
-#endif
-#ifdef ENABLE_GNSS_EXTERN
- || ((externalAutoDetect >= DETECTION_GNSS_0) && (externalAutoDetect <= DETECTION_GNSS_3))
-#endif
-
-#ifdef ENABLE_SENTINEL_MODE
- || ((protocol == EXT_INTERFACE_UART_SENTINEL) && (externalAutoDetect == DETECTION_SENTINEL))
-#endif
- )
- {
- lastSensorDataId = 0;
- externalUART_Protocol = protocol;
- MX_USART1_UART_DeInit();
- if( protocol != 0)
- {
- MX_USART1_UART_Init();
- }
- }
- break;
- default:
- break;
+ MX_USART1_UART_Init();
}
}
@@ -509,12 +486,17 @@
return externalCO2SignalStrength;
}
-void externalInterface_SetBottlePressure(uint8_t bottle, uint8_t bar)
+
+void externalInterface_GetHUDSequence(uint8_t* pSequence, uint8_t* brightness)
{
- if(bottle < PRESSURE_BOTTLE_CNT)
- {
- externalBottleBar[bottle] = bar;
- }
+ memcpy(pSequence, externalHUDSequence, EXT_INTERFACE_HUD_LED_MAX);
+ *brightness = externalHUDBrightness;
+}
+
+void externalInterface_SetHUDSequence(uint8_t* pSequence, uint8_t brightness)
+{
+ memcpy(externalHUDSequence, pSequence, EXT_INTERFACE_HUD_LED_MAX);
+ externalHUDBrightness = brightness;
}
uint8_t externalInterface_GetBottlePressure(uint8_t bottle)
@@ -528,6 +510,30 @@
return ret;
}
+void externalInterface_SetBottlePressure(uint8_t bottle, uint8_t bar)
+{
+ if(bottle < PRESSURE_BOTTLE_CNT)
+ {
+ externalBottleBar[bottle] = bar;
+ }
+}
+
+void externalInterface_CopySensorData(uint8_t sensorId, uint8_t* target, uint8_t* source)
+{
+ if(sensorId < EXT_INTERFACE_SENSOR_CNT)
+ {
+ switch(SensorMap[sensorId])
+ {
+ case SENSOR_DIGO2M:
+ case SENSOR_DIGO2: memcpy(target, source, sizeof(SSensorDataDiveO2));
+ break;
+ case SENSOR_HUD: memcpy(target, source, HUD_INFO_DATA_LENGTH);
+ break;
+ default:
+ break;
+ }
+ }
+}
uint8_t externalInterface_GetSensorData(uint8_t sensorId, uint8_t* pDataStruct)
{
@@ -540,7 +546,7 @@
if((pDataStruct != NULL) && (localId <= EXT_INTERFACE_SENSOR_CNT))
{
- memcpy(pDataStruct, &sensorDataDiveO2[localId], sizeof(SSensorDataDiveO2));
+ externalInterface_CopySensorData(localId, pDataStruct, &sensorData[localId][0]);
}
else
{
@@ -568,7 +574,7 @@
{
if((sensorId != 0xFF) && (sensorId < EXT_INTERFACE_SENSOR_CNT))
{
- memcpy(&sensorDataDiveO2[sensorId], pDataStruct, sizeof(SSensorDataDiveO2));
+ externalInterface_CopySensorData(sensorId, &sensorData[sensorId][0], pDataStruct);
lastSensorDataId = sensorId;
if(sensorId >= MAX_ADC_CHANNEL)
{
@@ -576,7 +582,7 @@
{
if(Mux2ADCMap[index] == sensorId)
{
- memcpy(&sensorDataDiveO2[index], pDataStruct, sizeof(SSensorDataDiveO2));
+ externalInterface_CopySensorData(index, &sensorData[index][0], pDataStruct);
lastSensorDataId = index;
break;
}
@@ -585,7 +591,7 @@
}
else
{
- memset(&sensorDataDiveO2,0,sizeof(sensorDataDiveO2));
+ memset(&sensorData,0,EXTIF_SENSOR_INFO_SIZE * EXT_INTERFACE_SENSOR_CNT);
lastSensorDataId = 0xFF;
}
}
@@ -858,13 +864,17 @@
{
-#if defined ENABLE_SENTINEL_MODE || defined ENABLE_GNSS_EXTERN
+#if defined ENABLE_SENTINEL_MODE || defined ENABLE_GNSS_EXTERN || defined ENABLE_HUD_SUPPORT
#ifdef ENABLE_GNSS_EXTERN
externalAutoDetect = DETECTION_GNSS_0;
externalInterface_SwitchUART(EXT_INTERFACE_UART_GNSS);
#else
#ifdef ENABLE_SENTINEL_MODE
externalAutoDetect = DETECTION_SENTINEL;
+#else
+#ifdef ENABLE_HUD_SUPPORT
+ externalAutoDetect = DETECTION_HUD_0;
+#endif
#endif
#endif
#else
@@ -958,6 +968,51 @@
}
externalAutoDetect++;
#endif
+
+#ifdef ENABLE_HUD_SUPPORT
+ if(externalAutoDetect == DETECTION_HUD_0)
+ {
+ tmpSensorMap[uartMuxChannel + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
+ if(foundSensorMap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)
+ {
+ externalInterface_CheckBaudrate(SENSOR_DIGO2);
+ UART_MUX_SelectAddress(0);
+ }
+ activeUartChannel = 0;
+ tmpSensorMap[uartMuxChannel - 1 + EXT_INTERFACE_MUX_OFFSET] = SENSOR_NONE;
+ uartMuxChannel = 1;
+ tmpSensorMap[EXT_INTERFACE_MUX_OFFSET] = SENSOR_HUD;
+ externalInterface_SensorState[EXT_INTERFACE_MUX_OFFSET] = UART_COMMON_INIT;
+ externalInterface_CheckBaudrate(SENSOR_HUD);
+ externalInterfaceMuxReqIntervall = 500; /* iterations needed for module config */
+ }
+ break;
+ case DETECTION_HUD_0:
+ case DETECTION_HUD_1:
+ case DETECTION_HUD_2:
+ case DETECTION_HUD_3:
+ if(uartHUD_isSensorConnected())
+ {
+ foundSensorMap[EXT_INTERFACE_MUX_OFFSET + activeUartChannel] = SENSOR_HUD;
+ externalAutoDetect = DETECTION_DONE; /* only one HUD sensor supported */
+ }
+ else if(foundSensorMap[EXT_INTERFACE_SENSOR_CNT-1] == SENSOR_MUX)
+ {
+ externalInterface_CheckBaudrate(SENSOR_DIGO2);
+ 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_CheckBaudrate(SENSOR_HUD);
+ externalAutoDetect++;
+ uartMuxChannel++;
+ }
+ else
+ {
+ externalAutoDetect = DETECTION_DONE;
+ }
+#endif
break;
case DETECTION_DONE: externalAutoDetect = DETECTION_OFF;
externalInterface_SwitchUART(EXT_INTERFACE_UART_OFF);
@@ -971,7 +1026,7 @@
cntSensor++;
}
- if((foundSensorMap[index] == SENSOR_DIGO2) || (foundSensorMap[index] == SENSOR_CO2) || (foundSensorMap[index] == SENSOR_GNSS))
+ if((foundSensorMap[index] == SENSOR_DIGO2) || (foundSensorMap[index] == SENSOR_CO2) || (foundSensorMap[index] == SENSOR_GNSS) || (foundSensorMap[index] == SENSOR_HUD))
{
cntUARTSensor++;
}
@@ -986,23 +1041,22 @@
}
externalInface_MapUartToLegacyADC(foundSensorMap);
externalInterfaceMuxReqIntervall = 0xFFFF;
- if(cntSensor == 0) /* return default sensor map if no sensor at all has been detected */
+ if((cntSensor == 0) /* return default sensor map if no sensor at all has been detected */
+ || ((foundSensorMap[0] == SENSOR_NONE) && (foundSensorMap[1] == SENSOR_NONE) && (foundSensorMap[2] == SENSOR_NONE)))
{
foundSensorMap[0] = SENSOR_OPTIC;
foundSensorMap[1] = SENSOR_OPTIC;
foundSensorMap[2] = SENSOR_OPTIC;
}
- else
+ if(cntUARTSensor != 0)
{
- if(cntUARTSensor != 0)
+ externalInterfaceMuxReqIntervall = REQUEST_INT_SENSOR_MS / cntUARTSensor;
+ if(foundSensorMap[0] == SENSOR_SENTINELM) /* special case: Sentinel sends combined data */
{
- externalInterfaceMuxReqIntervall = REQUEST_INT_SENSOR_MS / cntUARTSensor;
- if(foundSensorMap[0] == SENSOR_SENTINELM) /* special case: Sentinel sends combined data */
- {
- externalInterfaceMuxReqIntervall = 4000;
- }
+ externalInterfaceMuxReqIntervall = 4000;
}
}
+
memcpy(SensorMap, foundSensorMap, sizeof(foundSensorMap));
memset(externalInterface_SensorState, UART_COMMON_INIT, sizeof(externalInterface_SensorState));
break;
@@ -1075,7 +1129,20 @@
externalInterface_SensorState[index] = UART_O2_CHECK;
}
break;
-
+#ifdef ENABLE_HUD_SUPPORT
+ case EXT_INTERFACE_HUD_UPDATE: index = (Cmd >> 8) & 0x000F;
+ if(SensorMap[index] == SENSOR_HUD)
+ {
+ externalInterface_SensorState[index] = UART_HUD_UPDATE;
+ }
+ break;
+ case EXT_INTERFACE_HUD_ABORT: index = (Cmd >> 8) & 0x000F;
+ if(SensorMap[index] == SENSOR_HUD)
+ {
+ externalInterface_SensorState[index] = UART_HUD_ABORT;
+ }
+ break;
+#endif
default:
break;
}
@@ -1101,7 +1168,8 @@
}
if(((pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_DIGO2)
|| (pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_CO2)
- || (pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_GNSS))
+ || (pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_GNSS)
+ || (pmap[index + EXT_INTERFACE_MUX_OFFSET] == SENSOR_HUD))
&& (index != activeUartChannel))
{
newChannel = index;
@@ -1122,6 +1190,7 @@
case SENSOR_SENTINEL:
case SENSOR_CO2: newBaudrate = 9600;
break;
+ case SENSOR_HUD:
case SENSOR_DIGO2:
default: newBaudrate = 19200;
break;
@@ -1286,6 +1355,10 @@
case SENSOR_SENTINEL: uartSentinel_Control();
break;
#endif
+#ifdef ENABLE_HUD_SUPPORT
+ case SENSOR_HUD: uartHUD_Control();
+ break;
+#endif
default:
break;
}
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Src/scheduler.c
--- a/Small_CPU/Src/scheduler.c Sun Feb 22 21:23:57 2026 +0100
+++ b/Small_CPU/Src/scheduler.c Mon Mar 02 17:22:25 2026 +0100
@@ -336,7 +336,10 @@
{
externalInterface_SwitchADC(1-externalInterface_isEnabledADC());
}
-
+ if((global.dataSendToSlave.data.externalInterface_Cmd & 0x00FF) == EXT_INTERFACE_HUD_UPDATE) /* update HUD sequence */
+ {
+ externalInterface_SetHUDSequence(global.dataSendToSlave.data.externalInterface_HUD_Update, global.dataSendToSlave.data.externalInterface_HUD_Brightness);
+ }
externalInface_SetSensorMap(global.dataSendToSlave.data.externalInterface_SensorMap);
if(global.dataSendToSlave.data.externalInterface_Cmd & 0x00FF) /* lowest nibble for commands */
{
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Src/uart.c
--- a/Small_CPU/Src/uart.c Sun Feb 22 21:23:57 2026 +0100
+++ b/Small_CPU/Src/uart.c Mon Mar 02 17:22:25 2026 +0100
@@ -24,6 +24,7 @@
#include "uartProtocol_Co2.h"
#include "uartProtocol_Sentinel.h"
#include "uartProtocol_GNSS.h"
+#include "uartProtocol_HUD.h"
#include "externalInterface.h"
#include "data_exchange.h"
#include "gpio.h"
@@ -199,11 +200,8 @@
}
}
-
-void UART_SendCmdString(uint8_t *cmdString)
+void UART_SendCmdRaw(const uint8_t *cmd, uint8_t cmdLength)
{
- uint8_t cmdLength = strlen((char*)cmdString);
-
if(Uart1Ctrl.dmaTxActive == 0)
{
if(cmdLength < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */
@@ -212,7 +210,7 @@
{
UART_StartDMA_Receiption(&Uart1Ctrl);
}
- memcpy(txBuffer, cmdString, cmdLength);
+ memcpy(txBuffer, cmd, cmdLength);
if(HAL_OK == HAL_UART_Transmit_DMA(&huart1,txBuffer,cmdLength))
{
Uart1Ctrl.dmaTxActive = 1;
@@ -222,11 +220,18 @@
}
else
{
- memcpy(txBufferQue, cmdString, cmdLength);
+ memcpy(txBufferQue, cmd, cmdLength);
Uart1Ctrl.txBufferQueLen = cmdLength;
}
}
+void UART_SendCmdString(uint8_t *cmdString)
+{
+ uint8_t cmdLength = strlen((char*)cmdString);
+
+ UART_SendCmdRaw(cmdString, cmdLength);
+}
+
void UART_AddFletcher(uint8_t* pBuffer, uint8_t length)
{
uint8_t ck_A = 0;
@@ -459,6 +464,10 @@
case SENSOR_SENTINEL: uartSentinel_ProcessData(pUartCtrl->pRxBuffer[localRX]);
break;
#endif
+#ifdef ENABLE_HUD_SUPPORT
+ case SENSOR_HUD: uartHUD_ProcessData(pUartCtrl->pRxBuffer[localRX]);
+ break;
+#endif
default:
break;
}
diff -r c87753e73eb8 -r bd8ab302ef4a Small_CPU/Src/uartProtocol_HUD.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Src/uartProtocol_HUD.c Mon Mar 02 17:22:25 2026 +0100
@@ -0,0 +1,186 @@
+/**
+ ******************************************************************************
+ * @file uartProtocol_HUD.c
+ * @author heinrichs weikamp gmbh
+ * @version V0.0.1
+ * @date 24-Feb-2026
+ * @brief Interface functionality to external, UART based HUD
+ *
+ @verbatim
+
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2023 heinrichs weikamp
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+
+#include
+#include
+#include "uart.h"
+#include "externalInterface.h"
+
+#ifdef ENABLE_HUD_SUPPORT
+static uint8_t HUDConnected = 0; /* Binary indicator if a sensor is connected or not */
+static receiveStateHUD_t rxState = HUDRX_Ready;
+
+
+
+void uartHUD_SendCmd(uint8_t HUDCmd)
+{
+ uint8_t cmdLength = 0;
+ uint8_t cmdBuf[HUD_MAX_CMD_LENGTH];
+ uint8_t index = 0;
+ uint16_t checkSum = 0;
+
+ cmdBuf[0] = HUD_CMD_BYTE_START;
+ switch (HUDCmd)
+ {
+ case HUDCMD_GETINFO: cmdBuf[1] = HUD_CMD_BYTE_INFO;
+ cmdLength = 1;
+ break;
+ case HUDCMD_UPDATE: cmdBuf[1] = HUD_CMD_BYTE_UPDATE;
+ externalInterface_GetHUDSequence(&cmdBuf[3],&cmdBuf[2]);
+ cmdLength = 19;
+ break;
+ case HUDCMD_ABORTSEQ: cmdBuf[1] = HUD_CMD_BYTE_STOP;
+ cmdLength = 1;
+ break;
+ default: cmdLength = 0;
+ break;
+ }
+ if(cmdLength != 0)
+ {
+ cmdLength++; /* add Startbyte */
+ for(index = 0; index < cmdLength; index++)
+ {
+ if(index > 2) /* hard coded number of pulses = 2 */
+ {
+ cmdBuf[index] |= 0x10;
+ }
+ checkSum += cmdBuf[index];
+ }
+ cmdBuf[cmdLength++] = (checkSum & 0x00FF); /* low byte */
+ cmdBuf[cmdLength++] = (checkSum >> 8); /* high byte */
+ UART_SendCmdRaw(cmdBuf,cmdLength);
+ }
+}
+
+
+void uartHUD_Control(void)
+{
+ static uint8_t cmdString[20];
+ static uint8_t cmdLength = 0;
+ static uint8_t lastComState = UART_HUD_INIT;
+
+ uint8_t activeSensor = externalInterface_GetActiveUartSensor();
+ uartHUDStatus_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+
+ if(localComState == UART_HUD_ERROR)
+ {
+ localComState = lastComState;
+ }
+
+ switch(localComState)
+ {
+ case UART_HUD_INIT: HUDConnected = 0;
+ UART_ReadData(SENSOR_HUD, 1); /* flush buffer */
+ UART_StartDMA_Receiption(&Uart1Ctrl);
+ localComState = UART_HUD_SETUP;
+ uartHUD_SendCmd(HUDCMD_GETINFO);
+ break;
+ case UART_HUD_SETUP: uartHUD_SendCmd(HUDCMD_GETINFO);
+ rxState = HUDRX_DetectStart;
+ break;
+ case UART_HUD_UPDATE: uartHUD_SendCmd(HUDCMD_UPDATE);
+ rxState = HUDRX_Ready;
+ break;
+ case UART_HUD_ABORT: uartHUD_SendCmd(HUDCMD_ABORTSEQ);
+ rxState = HUDRX_Ready;
+ break;
+ default: if(cmdLength != 0)
+ {
+ UART_SendCmdString(cmdString); /* resend last command */
+ cmdLength = 0;
+ }
+ break;
+ }
+ lastComState = localComState;
+ externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
+}
+
+void uartHUD_ProcessData(uint8_t data)
+{
+ static uint8_t dataValue[HUD_INFO_DATA_LENGTH];
+ static uint8_t dataIndex = 0;
+ static uint16_t checkSum = 0;
+ static uint16_t rxCheckSum = 0;
+ uint8_t activeSensor = externalInterface_GetActiveUartSensor();
+ uartHUDStatus_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
+
+ if((localComState == UART_HUD_SETUP) && (rxState == HUDRX_Ready))
+ {
+ rxState = HUDRX_DetectStart;
+ }
+ switch(rxState)
+ {
+ case HUDRX_DetectStart: if(data == 0xAA)
+ {
+ dataIndex = 0;
+ memset(dataValue,0,HUD_INFO_DATA_LENGTH);
+ dataValue[dataIndex++] = data;
+ checkSum = data;
+ rxState = HUDRX_RXData;
+ }
+ break;
+ case HUDRX_RXData: dataValue[dataIndex++] = data;
+ checkSum += data;
+ if(dataIndex == HUD_INFO_DATA_LENGTH)
+ {
+ rxState = HUDRX_CheckSum_L;
+ }
+ break;
+ case HUDRX_CheckSum_L: rxCheckSum = data;
+ rxState++;
+ break;
+ case HUDRX_CheckSum_H: rxCheckSum |= (data << 8);
+ if(checkSum == rxCheckSum)
+ {
+ HUDConnected = 1;
+ if(localComState == UART_HUD_SETUP)
+ {
+ externalInterface_SetSensorData(activeSensor + EXT_INTERFACE_MUX_OFFSET, &dataValue[1]);
+ localComState = UART_HUD_ABORT; /* reset default sequence */
+ }
+ }
+ rxState = HUDRX_DetectStart;
+ break;
+ default: if(data == 'K') /* OK respond from HUD */
+ {
+ localComState = UART_HUD_IDLE;
+ }
+ if(data == 'N') /* NOK respond from HUD */
+ {
+ localComState = UART_HUD_ERROR;
+ }
+ if(data == 0xff)
+ {
+ localComState = UART_HUD_IDLE;
+ }
+ break;
+ }
+
+ externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
+}
+
+uint8_t uartHUD_isSensorConnected()
+{
+ return HUDConnected;
+}
+
+#endif
+