comparison Small_CPU/Src/uartProtocol_Co2.c @ 798:e9eba334b942

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.
author Ideenmodellierer
date Mon, 07 Aug 2023 20:29:44 +0200
parents
children 9602a7338f28
comparison
equal deleted inserted replaced
797:acf6614dc396 798:e9eba334b942
1 /**
2 ******************************************************************************
3 * @file uartProtocol_Co2.c
4 * @author heinrichs weikamp gmbh
5 * @version V0.0.1
6 * @date 31-Jul-2023
7 * @brief Interface functionality to external, UART based CO2 sensors
8 *
9 @verbatim
10
11
12 @endverbatim
13 ******************************************************************************
14 * @attention
15 *
16 * <h2><center>&copy; COPYRIGHT(c) 2023 heinrichs weikamp</center></h2>
17 *
18 ******************************************************************************
19 */
20 /* Includes ------------------------------------------------------------------*/
21
22 #include <string.h>
23 #include <uartProtocol_Co2.h>
24 #include "uart.h"
25 #include "externalInterface.h"
26
27
28 #ifdef ENABLE_CO2_SUPPORT
29 static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */
30 static receiveState_t rxState = RX_Ready;
31
32
33
34 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */
35 float LED_ZeroOffset = 0.0;
36 float pCO2 = 0.0;
37
38
39
40 void uartCo2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint8_t *cmdLength)
41 {
42 switch (CO2Cmd)
43 {
44 case CO2CMD_MODE_POLL: *cmdLength = snprintf((char*)cmdString, 10, "K 2\r\n");
45 break;
46 case CO2CMD_MODE_STREAM: *cmdLength = snprintf((char*)cmdString, 10, "K 1\r\n");
47 break;
48 case CO2CMD_CALIBRATE: *cmdLength = snprintf((char*)cmdString, 10, "G\r\n");
49 break;
50 case CO2CMD_GETDATA: *cmdLength = snprintf((char*)cmdString, 10, "Q\r\n");
51 break;
52 case CO2CMD_GETSCALE: *cmdLength = snprintf((char*)cmdString, 10, ".\r\n");
53 break;
54 default: *cmdLength = 0;
55 break;
56 }
57 if(cmdLength != 0)
58 {
59 UART_SendCmdString(cmdString);
60 }
61 }
62
63
64 void uartCo2_Control(void)
65 {
66 static uint8_t cmdString[10];
67 static uint8_t cmdLength = 0;
68 static uint8_t lastComState = 0;
69
70 uint8_t activeSensor = externalInterface_GetActiveUartSensor();
71 uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
72
73 uint8_t *pmap = externalInterface_GetSensorMapPointer(0);
74
75
76 if(localComState == UART_CO2_ERROR)
77 {
78 localComState = lastComState;
79 }
80
81 if(localComState == UART_CO2_INIT)
82 {
83 externalInterface_SetCO2Scale(0.0);
84 UART_StartDMA_Receiption();
85 localComState = UART_CO2_SETUP;
86 }
87 if(localComState == UART_CO2_SETUP)
88 {
89 if(externalInterface_GetCO2Scale() == 0.0)
90 {
91 uartCo2_SendCmd(CO2CMD_GETSCALE, cmdString, &cmdLength);
92 }
93 else
94 {
95 localComState = UART_CO2_IDLE;
96 }
97 }
98 else
99 {
100 if(localComState == UART_CO2_CALIBRATE)
101 {
102 uartCo2_SendCmd(CO2CMD_CALIBRATE, cmdString, &cmdLength);
103 }
104 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 */
105 {
106 //if(cmdLength == 0) /* poll data */
107 if(localComState == UART_CO2_IDLE)
108 {
109 uartCo2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
110 localComState = UART_CO2_OPERATING;
111 }
112 else /* resend last command */
113 {
114 UART_SendCmdString(cmdString);
115 cmdLength = 0;
116 }
117 }
118 else
119 {
120 localComState = UART_CO2_OPERATING; /* sensor in streaming mode if not connected to mux => operating */
121 }
122 }
123 lastComState = localComState;
124 externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
125 }
126
127
128 void uartCo2_ProcessData(uint8_t data)
129 {
130 static uint8_t dataType = 0;
131 static uint32_t dataValue = 0;
132 uint8_t activeSensor = externalInterface_GetActiveUartSensor();
133 uartCO2Status_t localComState = externalInterface_GetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET);
134
135 if(rxState == RX_Ready) /* identify data content */
136 {
137 switch(data)
138 {
139 case 'G':
140 case 'l':
141 case 'D':
142 case 'Z':
143 case '.': dataType = data;
144 rxState = RX_Data0;
145 dataValue = 0;
146 break;
147 case '?': localComState = UART_CO2_ERROR;
148 break;
149 default: /* unknown or corrupted => ignore */
150 break;
151 }
152 }
153 else if((data >= '0') && (data <= '9'))
154 {
155 if((rxState >= RX_Data0) && (rxState <= RX_Data4))
156 {
157 dataValue = dataValue * 10 + (data - '0');
158 rxState++;
159 if(rxState == RX_Data5)
160 {
161 rxState = RX_DataComplete;
162 CO2Connected = 1;
163 }
164 }
165 else /* protocol error data has max 5 digits */
166 {
167 rxState = RX_Ready;
168 }
169 }
170 if((data == ' ') || (data == '\n')) /* Abort data detection */
171 {
172 if(rxState == RX_DataComplete)
173 {
174 localComState = UART_CO2_IDLE;
175 if(externalInterface_GetCO2State() == 0)
176 {
177 externalInterface_SetCO2State(EXT_INTERFACE_33V_ON);
178 }
179 switch(dataType)
180 {
181 case 'D': externalInterface_SetCO2SignalStrength(dataValue);
182 break;
183 case 'l': LED_ZeroOffset = dataValue;
184 break;
185 case 'Z': externalInterface_SetCO2Value(dataValue);
186 break;
187 case '.': externalInterface_SetCO2Scale(dataValue);
188 break;
189 default: rxState = RX_Ready;
190 break;
191 }
192 }
193 if(rxState != RX_Data0) /* reset state machine because message in wrong format */
194 {
195 rxState = RX_Ready;
196 }
197 }
198 externalInterface_SetSensorState(activeSensor + EXT_INTERFACE_MUX_OFFSET,localComState);
199 }
200
201 uint8_t uartCo2_isSensorConnected()
202 {
203 return CO2Connected;
204 }
205
206 #endif
207