Mercurial > public > ostc4
comparison Small_CPU/Src/uart.c @ 729:d646a0f724a7
Added auto detection functionality for sensors connected to the external interface:
O2 sensors may be connected to the analog input as well as to the UART. The GUI visualization provides three slots for ppo2 display. Beside detection of sensor kind the task of the function is to place the available sensor in this three slots. CO2 has its own communication slot outside the ppo2 channel.
The result of the automatic detection is communicated via the sensor map.
author | Ideenmodellierer |
---|---|
date | Sat, 14 Jan 2023 20:46:17 +0100 |
parents | 621265ec3d23 |
children | 2a801cfe23ab |
comparison
equal
deleted
inserted
replaced
728:5143e927219f | 729:d646a0f724a7 |
---|---|
31 UART_HandleTypeDef huart1; | 31 UART_HandleTypeDef huart1; |
32 | 32 |
33 DMA_HandleTypeDef hdma_usart1_rx; | 33 DMA_HandleTypeDef hdma_usart1_rx; |
34 | 34 |
35 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow fariations in buffer read time */ | 35 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow fariations in buffer read time */ |
36 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ | 36 static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ |
37 static uint8_t rxReadIndex; /* Index at which new data is stared */ | 37 static uint8_t rxReadIndex; /* Index at which new data is stared */ |
38 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ | 38 static uint8_t lastCmdIndex; /* Index of last command which has not been completly received */ |
39 static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */ | 39 static uint8_t dmaActive; /* Indicator if DMA reception needs to be started */ |
40 static uint8_t digO2Connected = 0; /* Binary indicator if a sensor is connected or not */ | |
41 static uint8_t CO2Connected = 0; /* Binary indicator if a sensor is connected or not */ | |
42 static uint8_t ppO2TargetChannel = 0; /* The OSTC4 supports three slots for visualization of the ppo2. This one is reserved for the digital sensor */ | |
40 | 43 |
41 static SSensorDataDiveO2 sensorDataDiveO2; /* intermediate storage for additional sensor data */ | 44 static SSensorDataDiveO2 sensorDataDiveO2; /* intermediate storage for additional sensor data */ |
42 | 45 |
43 char tmpRxBuf[30]; | 46 char tmpRxBuf[30]; |
44 uint8_t tmpRxIdx = 0; | 47 uint8_t tmpRxIdx = 0; |
78 | 81 |
79 rxReadIndex = 0; | 82 rxReadIndex = 0; |
80 lastCmdIndex = 0; | 83 lastCmdIndex = 0; |
81 rxWriteIndex = 0; | 84 rxWriteIndex = 0; |
82 dmaActive = 0; | 85 dmaActive = 0; |
86 digO2Connected = 0; | |
87 CO2Connected = 0; | |
83 Comstatus_O2 = UART_O2_INIT; | 88 Comstatus_O2 = UART_O2_INIT; |
84 } | 89 } |
85 | 90 |
86 void MX_USART1_UART_DeInit(void) | 91 void MX_USART1_UART_DeInit(void) |
87 { | 92 { |
113 /* DMA interrupt init */ | 118 /* DMA interrupt init */ |
114 HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0); | 119 HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0); |
115 HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); | 120 HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); |
116 } | 121 } |
117 | 122 |
123 | |
124 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength) | |
125 { | |
126 switch (O2State) | |
127 { | |
128 case UART_O2_CHECK: *cmdLength = snprintf((char*)cmdString, 10, "#LOGO"); | |
129 break; | |
130 case UART_O2_REQ_INFO: *cmdLength = snprintf((char*)cmdString, 10, "#VERS"); | |
131 break; | |
132 case UART_O2_REQ_ID: *cmdLength = snprintf((char*)cmdString, 10, "#IDNR"); | |
133 break; | |
134 case UART_O2_REQ_O2: *cmdLength = snprintf((char*)cmdString, 10, "#DOXY"); | |
135 break; | |
136 case UART_O2_REQ_RAW: *cmdLength = snprintf((char*)cmdString, 10, "#DRAW"); | |
137 break; | |
138 default: *cmdLength = 0; | |
139 break; | |
140 } | |
141 if(*cmdLength != 0) | |
142 { | |
143 cmdString[*cmdLength] = 0x0D; | |
144 *cmdLength = *cmdLength + 1; | |
145 } | |
146 } | |
147 | |
148 void StringToInt(char *pstr, uint32_t *puInt32) | |
149 { | |
150 uint8_t index = 0; | |
151 uint32_t result = 0; | |
152 while((pstr[index] >= '0') && (pstr[index] <= '9')) | |
153 { | |
154 result *=10; | |
155 result += pstr[index] - '0'; | |
156 index++; | |
157 } | |
158 *puInt32 = result; | |
159 } | |
160 | |
161 void StringToUInt64(char *pstr, uint64_t *puint64) | |
162 { | |
163 uint8_t index = 0; | |
164 uint64_t result = 0; | |
165 while((pstr[index] >= '0') && (pstr[index] <= '9')) | |
166 { | |
167 result *=10; | |
168 result += pstr[index] - '0'; | |
169 index++; | |
170 } | |
171 *puint64 = result; | |
172 } | |
118 void ConvertByteToHexString(uint8_t byte, char* str) | 173 void ConvertByteToHexString(uint8_t byte, char* str) |
119 { | 174 { |
120 uint8_t worker = 0; | 175 uint8_t worker = 0; |
121 uint8_t digit = 0; | 176 uint8_t digit = 0; |
122 uint8_t digitCnt = 1; | 177 uint8_t digitCnt = 1; |
138 } | 193 } |
139 } | 194 } |
140 | 195 |
141 | 196 |
142 #ifdef ENABLE_CO2_SUPPORT | 197 #ifdef ENABLE_CO2_SUPPORT |
143 void HandleUARTCO2Data(void) | 198 void UART_HandleCO2Data(void) |
144 { | 199 { |
145 uint8_t localRX = rxReadIndex; | 200 uint8_t localRX = rxReadIndex; |
146 uint8_t dataType = 0; | 201 uint8_t dataType = 0; |
147 uint32_t dataValue = 0; | 202 uint32_t dataValue = 0; |
148 static receiveState_t rxState = RX_Ready; | 203 static receiveState_t rxState = RX_Ready; |
175 dataValue = dataValue * 10 + (rxBuffer[localRX] - '0'); | 230 dataValue = dataValue * 10 + (rxBuffer[localRX] - '0'); |
176 rxState++; | 231 rxState++; |
177 if(rxState == RX_Data5) | 232 if(rxState == RX_Data5) |
178 { | 233 { |
179 rxState = RX_DataComplete; | 234 rxState = RX_DataComplete; |
235 CO2Connected = 1; | |
180 } | 236 } |
181 } | 237 } |
182 else /* protocol error data has max 5 digits */ | 238 else /* protocol error data has max 5 digits */ |
183 { | 239 { |
184 rxState = RX_Ready; | 240 rxState = RX_Ready; |
219 } | 275 } |
220 | 276 |
221 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000) /* check for communication timeout */ | 277 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 2000) /* check for communication timeout */ |
222 { | 278 { |
223 externalInterface_SetCO2State(0); | 279 externalInterface_SetCO2State(0); |
280 CO2Connected = 0; | |
224 } | 281 } |
225 | 282 |
226 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ | 283 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ |
227 { | 284 { |
228 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) | 285 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) |
232 } | 289 } |
233 } | 290 } |
234 #endif | 291 #endif |
235 | 292 |
236 #ifdef ENABLE_SENTINEL_MODE | 293 #ifdef ENABLE_SENTINEL_MODE |
237 void HandleUARTSentinelData(void) | 294 void UART_HandleSentinelData(void) |
238 { | 295 { |
239 uint8_t localRX = rxReadIndex; | 296 uint8_t localRX = rxReadIndex; |
240 static uint8_t dataType = 0; | 297 static uint8_t dataType = 0; |
241 static uint32_t dataValue[3]; | 298 static uint32_t dataValue[3]; |
242 static uint8_t dataValueIdx = 0; | 299 static uint8_t dataValueIdx = 0; |
384 } | 441 } |
385 } | 442 } |
386 } | 443 } |
387 #endif | 444 #endif |
388 | 445 |
389 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength) | 446 |
390 { | 447 |
391 switch (O2State) | 448 void UART_HandleDigitalO2(void) |
392 { | |
393 case UART_O2_CHECK: *cmdLength = snprintf((char*)cmdString, 10, "#LOGO"); | |
394 break; | |
395 case UART_O2_REQ_INFO: *cmdLength = snprintf((char*)cmdString, 10, "#VERS"); | |
396 break; | |
397 case UART_O2_REQ_ID: *cmdLength = snprintf((char*)cmdString, 10, "#IDNR"); | |
398 break; | |
399 case UART_O2_REQ_O2: *cmdLength = snprintf((char*)cmdString, 10, "#DOXY"); | |
400 break; | |
401 case UART_O2_REQ_RAW: *cmdLength = snprintf((char*)cmdString, 10, "#DRAW"); | |
402 break; | |
403 default: *cmdLength = 0; | |
404 break; | |
405 } | |
406 if(*cmdLength != 0) | |
407 { | |
408 cmdString[*cmdLength] = 0x0D; | |
409 *cmdLength = *cmdLength + 1; | |
410 } | |
411 } | |
412 | |
413 void StringToInt(char *pstr, uint32_t *puInt32) | |
414 { | |
415 uint8_t index = 0; | |
416 uint32_t result = 0; | |
417 while((pstr[index] >= '0') && (pstr[index] <= '9')) | |
418 { | |
419 result *=10; | |
420 result += pstr[index] - '0'; | |
421 index++; | |
422 } | |
423 *puInt32 = result; | |
424 } | |
425 | |
426 void StringToUInt64(char *pstr, uint64_t *puint64) | |
427 { | |
428 uint8_t index = 0; | |
429 uint64_t result = 0; | |
430 while((pstr[index] >= '0') && (pstr[index] <= '9')) | |
431 { | |
432 result *=10; | |
433 result += pstr[index] - '0'; | |
434 index++; | |
435 } | |
436 *puint64 = result; | |
437 } | |
438 | |
439 void HandleUARTDigitalO2(void) | |
440 { | 449 { |
441 static uint32_t lastO2ReqTick = 0; | 450 static uint32_t lastO2ReqTick = 0; |
442 | 451 |
443 static uartO2RxState_t rxState = O2RX_IDLE; | 452 static uartO2RxState_t rxState = O2RX_IDLE; |
444 static uint32_t lastReceiveTick = 0; | 453 static uint32_t lastReceiveTick = 0; |
503 if(rxBuffer[localRX] == cmdString[cmdReadIndex]) | 512 if(rxBuffer[localRX] == cmdString[cmdReadIndex]) |
504 { | 513 { |
505 cmdReadIndex++; | 514 cmdReadIndex++; |
506 if(cmdReadIndex == cmdLength - 1) | 515 if(cmdReadIndex == cmdLength - 1) |
507 { | 516 { |
517 digO2Connected = 1; | |
508 tmpRxIdx = 0; | 518 tmpRxIdx = 0; |
509 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf)); | 519 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf)); |
510 switch (Comstatus_O2) | 520 switch (Comstatus_O2) |
511 { | 521 { |
512 case UART_O2_CHECK: Comstatus_O2 = UART_O2_REQ_ID; | 522 case UART_O2_CHECK: Comstatus_O2 = UART_O2_REQ_ID; |
563 case O2RX_GETTYPE: StringToInt(tmpRxBuf,&tmpData); | 573 case O2RX_GETTYPE: StringToInt(tmpRxBuf,&tmpData); |
564 rxState = O2RX_GETCHANNEL; | 574 rxState = O2RX_GETCHANNEL; |
565 break; | 575 break; |
566 | 576 |
567 case O2RX_GETO2: StringToInt(tmpRxBuf,&tmpO2); | 577 case O2RX_GETO2: StringToInt(tmpRxBuf,&tmpO2); |
568 setExternalInterfaceChannel(0,(float)(tmpO2 / 10000.0)); | 578 setExternalInterfaceChannel(ppO2TargetChannel,(float)(tmpO2 / 10000.0)); |
569 rxState = O2RX_GETTEMP; | 579 rxState = O2RX_GETTEMP; |
570 break; | 580 break; |
571 case O2RX_GETTEMP: StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.temperature); | 581 case O2RX_GETTEMP: StringToInt(tmpRxBuf,(uint32_t*)&sensorDataDiveO2.temperature); |
572 rxState = O2RX_GETSTATUS; | 582 rxState = O2RX_GETSTATUS; |
573 break; | 583 break; |
622 break; | 632 break; |
623 default: rxState = O2RX_IDLE; | 633 default: rxState = O2RX_IDLE; |
624 break; | 634 break; |
625 | 635 |
626 } | 636 } |
627 | 637 rxBuffer[localRX] = 0; |
628 localRX++; | 638 localRX++; |
629 rxReadIndex++; | 639 rxReadIndex++; |
630 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) | 640 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) |
631 { | 641 { |
632 localRX = 0; | 642 localRX = 0; |
633 rxReadIndex = 0; | 643 rxReadIndex = 0; |
634 } | 644 } |
635 } | 645 } |
636 | 646 |
637 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */ | 647 if((digO2Connected) && time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */ |
638 { | 648 { |
649 digO2Connected = 0; | |
639 if(curAlive == lastAlive) | 650 if(curAlive == lastAlive) |
640 { | 651 { |
641 setExternalInterfaceChannel(0,0.0); | 652 setExternalInterfaceChannel(ppO2TargetChannel,0.0); |
642 setExternalInterfaceChannel(1,0.0); | |
643 setExternalInterfaceChannel(2,0.0); | |
644 } | 653 } |
645 lastAlive = curAlive; | 654 lastAlive = curAlive; |
646 } | 655 } |
647 | 656 |
648 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ | 657 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ |
652 dmaActive = 1; | 661 dmaActive = 1; |
653 } | 662 } |
654 } | 663 } |
655 } | 664 } |
656 | 665 |
666 uint8_t UART_isDigO2Connected() | |
667 { | |
668 return digO2Connected; | |
669 } | |
670 uint8_t UART_isCO2Connected() | |
671 { | |
672 return CO2Connected; | |
673 } | |
674 | |
675 | |
676 void UART_setTargetChannel(uint8_t channel) | |
677 { | |
678 ppO2TargetChannel = channel; | |
679 } | |
657 | 680 |
658 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) | 681 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) |
659 { | 682 { |
660 if(huart == &huart1) | 683 if(huart == &huart1) |
661 { | 684 { |
679 } | 702 } |
680 } | 703 } |
681 | 704 |
682 | 705 |
683 | 706 |
684 | |
685 | |
686 | |
687 | |
688 | |
689 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ | 707 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ |