comparison Small_CPU/Src/uart.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 bb37d4f3e50e
children 96ffad0a4e57
comparison
equal deleted inserted replaced
797:acf6614dc396 798:e9eba334b942
19 ****************************************************************************** 19 ******************************************************************************
20 */ 20 */
21 /* Includes ------------------------------------------------------------------*/ 21 /* Includes ------------------------------------------------------------------*/
22 #include "uart.h" 22 #include "uart.h"
23 #include "uartProtocol_O2.h" 23 #include "uartProtocol_O2.h"
24 #include "uartProtocol_Co2.h"
24 #include "externalInterface.h" 25 #include "externalInterface.h"
25 #include "data_exchange.h" 26 #include "data_exchange.h"
26 #include <string.h> /* memset */ 27 #include <string.h> /* memset */
27 28
28 /* Private variables ---------------------------------------------------------*/ 29 /* Private variables ---------------------------------------------------------*/
40 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ 41 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */
41 static uint8_t rxReadIndex; /* Index at which new data is stared */ 42 static uint8_t rxReadIndex; /* Index at which new data is stared */
42 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ 43 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */
43 static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */ 44 static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */
44 45
45 static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */ 46
46 static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */ 47 static uint8_t SentinelConnected = 0; /* Binary indicator if a sensor is connected or not */
47 48
48 49
49
50 static uartCO2Status_t ComStatus_CO2 = UART_CO2_INIT;
51
52 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */
53 float LED_ZeroOffset = 0.0;
54 float pCO2 = 0.0;
55 /* Exported functions --------------------------------------------------------*/ 50 /* Exported functions --------------------------------------------------------*/
56 51
57
58
59 //huart.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), new_baudrate);
60 52
61 void MX_USART1_UART_Init(void) 53 void MX_USART1_UART_Init(void)
62 { 54 {
63 /* regular init */ 55 /* regular init */
64 56
69 huart1.Init.BaudRate = 19200; 61 huart1.Init.BaudRate = 19200;
70 } 62 }
71 else 63 else
72 { 64 {
73 huart1.Init.BaudRate = 9600; 65 huart1.Init.BaudRate = 9600;
74 ComStatus_CO2 = UART_CO2_INIT;
75 } 66 }
76 huart1.Init.WordLength = UART_WORDLENGTH_8B; 67 huart1.Init.WordLength = UART_WORDLENGTH_8B;
77 huart1.Init.StopBits = UART_STOPBITS_1; 68 huart1.Init.StopBits = UART_STOPBITS_1;
78 huart1.Init.Parity = UART_PARITY_NONE; 69 huart1.Init.Parity = UART_PARITY_NONE;
79 huart1.Init.Mode = UART_MODE_TX_RX; 70 huart1.Init.Mode = UART_MODE_TX_RX;
88 rxReadIndex = 0; 79 rxReadIndex = 0;
89 lastCmdIndex = 0; 80 lastCmdIndex = 0;
90 rxWriteIndex = 0; 81 rxWriteIndex = 0;
91 dmaActive = 0; 82 dmaActive = 0;
92 83
93 CO2Connected = 0;
94 SentinelConnected = 0; 84 SentinelConnected = 0;
95 85
96 } 86 }
97 87
98 void MX_USART1_UART_DeInit(void) 88 void MX_USART1_UART_DeInit(void)
155 } 145 }
156 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10); 146 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10);
157 } 147 }
158 } 148 }
159 149
160 void DigitalCO2_SendCmd(uint8_t CO2Cmd, uint8_t *cmdString, uint16_t *cmdLength)
161 {
162 switch (CO2Cmd)
163 {
164 case CO2CMD_MODE_POLL: *cmdLength = snprintf((char*)cmdString, 10, "K 2\r\n");
165 break;
166 case CO2CMD_MODE_STREAM: *cmdLength = snprintf((char*)cmdString, 10, "K 1\r\n");
167 break;
168 case CO2CMD_CALIBRATE: *cmdLength = snprintf((char*)cmdString, 10, "G\r\n");
169 break;
170 case CO2CMD_GETDATA: *cmdLength = snprintf((char*)cmdString, 10, "Q\r\n");
171 break;
172 case CO2CMD_GETSCALE: *cmdLength = snprintf((char*)cmdString, 10, ".\r\n");
173 break;
174 default: *cmdLength = 0;
175 break;
176 }
177 if(cmdLength != 0)
178 {
179 HAL_UART_Transmit(&huart1,cmdString,*cmdLength,10);
180 }
181 }
182 150
183 void StringToInt(char *pstr, uint32_t *puInt32) 151 void StringToInt(char *pstr, uint32_t *puInt32)
184 { 152 {
185 uint8_t index = 0; 153 uint8_t index = 0;
186 uint32_t result = 0; 154 uint32_t result = 0;
228 } 196 }
229 } 197 }
230 198
231 void UART_StartDMA_Receiption() 199 void UART_StartDMA_Receiption()
232 { 200 {
233 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) 201 if(dmaActive == 0)
234 { 202 {
235 dmaActive = 1; 203 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE))
236 } 204 {
237 } 205 dmaActive = 1;
238 206 }
239 #ifdef ENABLE_CO2_SUPPORT 207 }
240 void UART_HandleCO2Data(void) 208 }
241 { 209
242 uint8_t localRX = rxReadIndex; 210 void UART_ChangeBaudrate(uint32_t newBaudrate)
243 static uint8_t dataType = 0; 211 {
244 static uint32_t dataValue = 0; 212
245 static receiveState_t rxState = RX_Ready; 213 // HAL_DMA_Abort(&hdma_usart1_rx);
246 static uint32_t lastReceiveTick = 0; 214 MX_USART1_UART_DeInit();
247 static uint32_t lastTransmitTick = 0; 215 //HAL_UART_Abort(&huart1);
248 static uint8_t cmdString[10]; 216 //HAL_DMA_DeInit(&hdma_usart1_rx);
249 static uint16_t cmdLength = 0; 217
250 218
251 uint32_t Tick = HAL_GetTick(); 219 // huart1.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq()/2, newBaudrate);
252 220 huart1.Init.BaudRate = newBaudrate;
253 uint8_t *pmap = externalInterface_GetSensorMapPointer(0); 221 HAL_UART_Init(&huart1);
254 222 MX_USART1_DMA_Init();
255 if(ComStatus_CO2 == UART_CO2_INIT) 223 if(dmaActive)
256 { 224 {
225 rxReadIndex = 0;
226 rxWriteIndex = 0;
227 dmaActive = 0;
257 UART_StartDMA_Receiption(); 228 UART_StartDMA_Receiption();
258 ComStatus_CO2 = UART_CO2_SETUP; 229 }
259 } 230 }
260
261 if(ComStatus_CO2 == UART_CO2_SETUP)
262 {
263 if(time_elapsed_ms(lastTransmitTick,Tick) > 200)
264 {
265 if(externalInterface_GetCO2Scale() == 0.0)
266 {
267 DigitalCO2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
268 lastTransmitTick = Tick;
269 }
270 else
271 {
272 ComStatus_CO2 = UART_CO2_OPERATING;
273 }
274 }
275 }
276 else
277 {
278 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 */
279 {
280 if(time_elapsed_ms(lastTransmitTick,Tick) > 2000) /* poll every two seconds */
281 {
282 lastTransmitTick = Tick;
283 if(cmdLength == 0) /* poll data */
284 {
285 DigitalCO2_SendCmd(CO2CMD_GETDATA, cmdString, &cmdLength);
286 }
287 else /* resend last command */
288 {
289 HAL_UART_Transmit(&huart1,cmdString,strlen((char*)cmdString),10);
290 cmdLength = 0;
291 }
292 }
293 }
294 }
295 while((rxBuffer[localRX]!=BUFFER_NODATA))
296 {
297 lastReceiveTick = Tick;
298 if(rxState == RX_Ready) /* identify data content */
299 {
300 switch(rxBuffer[localRX])
301 {
302 case 'l':
303 case 'D':
304 case 'Z':
305 case '.':
306 dataType = rxBuffer[localRX];
307 rxState = RX_Data0;
308 dataValue = 0;
309 break;
310
311 default: /* unknown or corrupted => ignore */
312 break;
313 }
314 }
315 else if((rxBuffer[localRX] >= '0') && (rxBuffer[localRX] <= '9'))
316 {
317 if((rxState >= RX_Data0) && (rxState <= RX_Data4))
318 {
319 dataValue = dataValue * 10 + (rxBuffer[localRX] - '0');
320 rxState++;
321 if(rxState == RX_Data5)
322 {
323 rxState = RX_DataComplete;
324 CO2Connected = 1;
325 }
326 }
327 else /* protocol error data has max 5 digits */
328 {
329 rxState = RX_Ready;
330 }
331 }
332 if((rxBuffer[localRX] == ' ') || (rxBuffer[localRX] == '\n')) /* Abort data detection */
333 {
334 if(rxState == RX_DataComplete)
335 {
336 if(externalInterface_GetCO2State() == 0)
337 {
338 externalInterface_SetCO2State(EXT_INTERFACE_33V_ON);
339 }
340 switch(dataType)
341 {
342 case 'D': externalInterface_SetCO2SignalStrength(dataValue);
343 break;
344 case 'l': LED_ZeroOffset = dataValue;
345 break;
346 case 'Z': externalInterface_SetCO2Value(dataValue);
347 break;
348 case '.': externalInterface_SetCO2Scale(dataValue);
349 break;
350 default: rxState = RX_Ready;
351 break;
352 }
353 }
354 if(rxState != RX_Data0) /* reset state machine because message in wrong format */
355 {
356 rxState = RX_Ready;
357 }
358 }
359 rxBuffer[localRX] = BUFFER_NODATA;
360 localRX++;
361 rxReadIndex++;
362 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER)
363 {
364 localRX = 0;
365 rxReadIndex = 0;
366 }
367 }
368
369 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000) /* check for communication timeout */
370 {
371 externalInterface_SetCO2State(0);
372 CO2Connected = 0;
373 }
374
375 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */
376 {
377 UART_StartDMA_Receiption();
378 }
379 }
380 #endif
381 231
382 #ifdef ENABLE_SENTINEL_MODE 232 #ifdef ENABLE_SENTINEL_MODE
383 void UART_HandleSentinelData(void) 233 void UART_HandleSentinelData(void)
384 { 234 {
385 uint8_t localRX = rxReadIndex; 235 uint8_t localRX = rxReadIndex;
529 } 379 }
530 } 380 }
531 #endif 381 #endif
532 382
533 383
534 uint8_t UART_isCO2Connected() 384
535 {
536 return CO2Connected;
537 }
538 uint8_t UART_isSentinelConnected() 385 uint8_t UART_isSentinelConnected()
539 { 386 {
540 return SentinelConnected; 387 return SentinelConnected;
541 } 388 }
542 389
569 switch (sensorType) 416 switch (sensorType)
570 { 417 {
571 case SENSOR_MUX: 418 case SENSOR_MUX:
572 case SENSOR_DIGO2: uartO2_ProcessData(rxBuffer[localRX]); 419 case SENSOR_DIGO2: uartO2_ProcessData(rxBuffer[localRX]);
573 break; 420 break;
574 // case SENSOR_CO2: uartCO2_Control(); 421 #ifdef ENABLE_CO2_SUPPORT
575 break; 422 case SENSOR_CO2: uartCo2_ProcessData(rxBuffer[localRX]);
423 break;
424 #endif
576 default: 425 default:
577 break; 426 break;
578 } 427 }
579 428
580 rxBuffer[localRX] = BUFFER_NODATA; 429 rxBuffer[localRX] = BUFFER_NODATA;