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****/