Mercurial > public > ostc4
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; |