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; |
