Mercurial > public > ostc4
comparison Small_CPU/Src/uart.c @ 704:f1b40364b0af
Added protocol functions for UART DiveO2 sensor:
The code has been modified to support the handling of several protocols (including baud rate changes). The data is requested by polling and passed via DMA into a ringbuffer which is then parsed by a cyclic function call in the main loop. At the moment only the O2 values are forwarded but because the sensor send several types of data within a signle message already more is extracted but yet discarded.
author | Ideenmodellierer |
---|---|
date | Fri, 28 Oct 2022 20:49:21 +0200 |
parents | fca2bd25e6e2 |
children | 045ff7800501 |
comparison
equal
deleted
inserted
replaced
703:2f457024049b | 704:f1b40364b0af |
---|---|
20 */ | 20 */ |
21 /* Includes ------------------------------------------------------------------*/ | 21 /* Includes ------------------------------------------------------------------*/ |
22 #include "uart.h" | 22 #include "uart.h" |
23 #include "externalInterface.h" | 23 #include "externalInterface.h" |
24 #include "data_exchange.h" | 24 #include "data_exchange.h" |
25 #include <string.h> /* memset */ | |
25 | 26 |
26 /* Private variables ---------------------------------------------------------*/ | 27 /* Private variables ---------------------------------------------------------*/ |
27 | 28 |
28 #define CHUNK_SIZE (20u) /* the DMA will handle chunk size transfers */ | 29 #define CHUNK_SIZE (20u) /* the DMA will handle chunk size transfers */ |
29 #define CHUNKS_PER_BUFFER (3u) | 30 #define CHUNKS_PER_BUFFER (3u) |
35 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 */ |
36 static uint8_t rxReadIndex; /* Index at which new data is stared */ | 37 static uint8_t rxReadIndex; /* Index at which new data is stared */ |
37 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 */ |
38 static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */ | 39 static uint8_t dmaActive; /* Indicator if DMA receiption needs to be started */ |
39 | 40 |
41 char tmpRxBuf[30]; | |
42 uint8_t tmpRxIdx = 0; | |
43 | |
44 static uartO2Status_t Comstatus_O2 = UART_O2_INIT; | |
45 | |
46 static uint32_t DigitalO2ID = 0; | |
47 | |
40 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ | 48 float LED_Level = 0.0; /* Normalized LED value which may be used as indication for the health status of the sensor */ |
41 float LED_ZeroOffset = 0.0; | 49 float LED_ZeroOffset = 0.0; |
42 float pCO2 = 0.0; | 50 float pCO2 = 0.0; |
43 /* Exported functions --------------------------------------------------------*/ | 51 /* Exported functions --------------------------------------------------------*/ |
44 | 52 |
45 void MX_USART1_UART_Init(void) | 53 void MX_USART1_UART_Init(void) |
46 { | 54 { |
47 /* regular init */ | 55 /* regular init */ |
48 | 56 |
49 huart1.Instance = USART1; | 57 huart1.Instance = USART1; |
50 huart1.Init.BaudRate = 9600; | 58 |
59 if(externalInterface_GetUARTProtocol() == 0x04) | |
60 { | |
61 huart1.Init.BaudRate = 19200; | |
62 Comstatus_O2 = UART_O2_INIT; | |
63 } | |
64 else | |
65 { | |
66 huart1.Init.BaudRate = 9600; | |
67 } | |
51 huart1.Init.WordLength = UART_WORDLENGTH_8B; | 68 huart1.Init.WordLength = UART_WORDLENGTH_8B; |
52 huart1.Init.StopBits = UART_STOPBITS_1; | 69 huart1.Init.StopBits = UART_STOPBITS_1; |
53 huart1.Init.Parity = UART_PARITY_NONE; | 70 huart1.Init.Parity = UART_PARITY_NONE; |
54 huart1.Init.Mode = UART_MODE_TX_RX; | 71 huart1.Init.Mode = UART_MODE_TX_RX; |
55 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; | 72 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; |
56 huart1.Init.OverSampling = UART_OVERSAMPLING_16; | 73 huart1.Init.OverSampling = UART_OVERSAMPLING_16; |
57 | 74 |
58 HAL_UART_Init(&huart1); | 75 HAL_UART_Init(&huart1); |
59 | 76 |
77 MX_USART1_DMA_Init(); | |
78 | |
60 rxReadIndex = 0; | 79 rxReadIndex = 0; |
61 lastCmdIndex = 0; | 80 lastCmdIndex = 0; |
62 rxWriteIndex = 0; | 81 rxWriteIndex = 0; |
63 dmaActive = 0; | 82 dmaActive = 0; |
83 Comstatus_O2 = UART_O2_INIT; | |
64 } | 84 } |
65 | 85 |
66 void MX_USART1_UART_DeInit(void) | 86 void MX_USART1_UART_DeInit(void) |
67 { | 87 { |
88 HAL_DMA_Abort(&hdma_usart1_rx); | |
68 HAL_DMA_DeInit(&hdma_usart1_rx); | 89 HAL_DMA_DeInit(&hdma_usart1_rx); |
69 HAL_UART_DeInit(&huart1); | 90 HAL_UART_DeInit(&huart1); |
70 } | 91 } |
71 | 92 |
72 void MX_USART1_DMA_Init() | 93 void MX_USART1_DMA_Init() |
354 } | 375 } |
355 } | 376 } |
356 } | 377 } |
357 #endif | 378 #endif |
358 | 379 |
380 void DigitalO2_SetupCmd(uint8_t O2State, uint8_t *cmdString, uint8_t *cmdLength) | |
381 { | |
382 switch (O2State) | |
383 { | |
384 case UART_O2_CHECK: *cmdLength = snprintf((char*)cmdString, 10, "#LOGO"); | |
385 break; | |
386 case UART_O2_REQ_INFO: *cmdLength = snprintf((char*)cmdString, 10, "#VERS"); | |
387 break; | |
388 case UART_O2_REQ_ID: *cmdLength = snprintf((char*)cmdString, 10, "#IDNR"); | |
389 break; | |
390 case UART_O2_REQ_O2: *cmdLength = snprintf((char*)cmdString, 10, "#DOXY"); | |
391 break; | |
392 | |
393 default: *cmdLength = 0; | |
394 break; | |
395 } | |
396 if(*cmdLength != 0) | |
397 { | |
398 cmdString[*cmdLength] = 0x0D; | |
399 *cmdLength = *cmdLength + 1; | |
400 } | |
401 } | |
402 | |
403 void StringToInt(char *pstr, uint32_t *pInt) | |
404 { | |
405 uint8_t index = 0; | |
406 uint32_t result = 0; | |
407 while((pstr[index] >= '0') && (pstr[index] <= '9')) | |
408 { | |
409 result *=10; | |
410 result += pstr[index] - '0'; | |
411 index++; | |
412 } | |
413 *pInt = result; | |
414 } | |
415 | |
416 void HandleUARTDigitalO2(void) | |
417 { | |
418 static uint32_t lastO2ReqTick = 0; | |
419 | |
420 static uartO2RxState_t rxState = O2RX_IDLE; | |
421 static uint32_t lastReceiveTick = 0; | |
422 static uint8_t lastAlive = 0; | |
423 static uint8_t curAlive = 0; | |
424 | |
425 static uint8_t cmdLength = 0; | |
426 static uint8_t cmdString[10]; | |
427 static uint8_t cmdReadIndex = 0; | |
428 | |
429 uint32_t tmpO2 = 0; | |
430 uint32_t tmpData = 0; | |
431 uint8_t localRX = rxReadIndex; | |
432 uint32_t tick = HAL_GetTick(); | |
433 | |
434 | |
435 if(Comstatus_O2 == UART_O2_INIT) | |
436 { | |
437 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE); | |
438 lastAlive = 0; | |
439 curAlive = 0; | |
440 | |
441 Comstatus_O2 = UART_O2_CHECK; | |
442 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); | |
443 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10); | |
444 | |
445 rxState = O2RX_CONFIRM; | |
446 cmdReadIndex = 0; | |
447 lastO2ReqTick = tick; | |
448 | |
449 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) | |
450 { | |
451 dmaActive = 1; | |
452 } | |
453 } | |
454 if(time_elapsed_ms(lastO2ReqTick,tick) > 1000) /* repeat request once per second */ | |
455 { | |
456 lastO2ReqTick = tick; | |
457 if(Comstatus_O2 == UART_O2_IDLE) /* cyclic request of o2 value */ | |
458 { | |
459 Comstatus_O2 = UART_O2_REQ_O2; | |
460 rxState = O2RX_CONFIRM; | |
461 } | |
462 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); | |
463 | |
464 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10); | |
465 } | |
466 | |
467 while((rxBuffer[localRX]!=0)) | |
468 { | |
469 | |
470 lastReceiveTick = tick; | |
471 switch(rxState) | |
472 { | |
473 case O2RX_CONFIRM: if(rxBuffer[localRX] == '#') | |
474 { | |
475 cmdReadIndex = 0; | |
476 } | |
477 if(rxBuffer[localRX] == cmdString[cmdReadIndex]) | |
478 { | |
479 cmdReadIndex++; | |
480 if(cmdReadIndex == cmdLength - 1) | |
481 { | |
482 tmpRxIdx = 0; | |
483 memset((char*) tmpRxBuf, 0, sizeof(tmpRxBuf)); | |
484 switch (Comstatus_O2) | |
485 { | |
486 case UART_O2_CHECK: Comstatus_O2 = UART_O2_REQ_INFO; | |
487 DigitalO2_SetupCmd(Comstatus_O2,cmdString,&cmdLength); | |
488 HAL_UART_Transmit(&huart1,cmdString,cmdLength,10); | |
489 break; | |
490 case UART_O2_REQ_ID: rxState = O2RX_GETNR; | |
491 break; | |
492 case UART_O2_REQ_INFO: rxState = O2RX_GETTYPE; | |
493 break; | |
494 case UART_O2_REQ_O2: rxState = O2RX_GETO2; | |
495 break; | |
496 default: Comstatus_O2 = UART_O2_IDLE; | |
497 rxState = O2RX_IDLE; | |
498 break; | |
499 } | |
500 } | |
501 } | |
502 break; | |
503 | |
504 case O2RX_GETSTATUS: | |
505 case O2RX_GETTEMP: | |
506 case O2RX_GETTYPE: | |
507 case O2RX_GETVERSION: | |
508 case O2RX_GETCHANNEL: | |
509 case O2RX_GETSUBSENSORS: | |
510 case O2RX_GETO2: | |
511 case O2RX_GETNR: if(rxBuffer[localRX] != 0x0D) | |
512 { | |
513 if(rxBuffer[localRX] != ' ') | |
514 { | |
515 tmpRxBuf[tmpRxIdx++] = rxBuffer[localRX]; | |
516 } | |
517 else | |
518 { | |
519 if(tmpRxIdx != 0) | |
520 { | |
521 switch(rxState) | |
522 { | |
523 case O2RX_GETCHANNEL: StringToInt(tmpRxBuf,&tmpData); | |
524 rxState = O2RX_GETVERSION; | |
525 break; | |
526 case O2RX_GETVERSION: StringToInt(tmpRxBuf,&tmpData); | |
527 rxState = O2RX_GETSUBSENSORS; | |
528 break; | |
529 case O2RX_GETTYPE: StringToInt(tmpRxBuf,&tmpData); | |
530 rxState = O2RX_GETCHANNEL; | |
531 break; | |
532 | |
533 case O2RX_GETO2: StringToInt(tmpRxBuf,&tmpO2); | |
534 setExternalInterfaceChannel(0,(float)(tmpO2 / 10000.0)); | |
535 rxState = O2RX_GETTEMP; | |
536 break; | |
537 case O2RX_GETTEMP: rxState = O2RX_GETSTATUS; | |
538 break; | |
539 default: | |
540 break; | |
541 } | |
542 memset((char*) tmpRxBuf, 0, tmpRxIdx); | |
543 tmpRxIdx = 0; | |
544 } | |
545 } | |
546 } | |
547 else | |
548 { | |
549 switch (rxState) | |
550 { | |
551 case O2RX_GETSTATUS: StringToInt(tmpRxBuf,&tmpData); | |
552 Comstatus_O2 = UART_O2_IDLE; | |
553 rxState = O2RX_IDLE; | |
554 break; | |
555 case O2RX_GETSUBSENSORS: StringToInt(tmpRxBuf,&tmpData); | |
556 Comstatus_O2 = UART_O2_IDLE; | |
557 rxState = O2RX_IDLE; | |
558 break; | |
559 case O2RX_GETNR: StringToInt((char*)rxBuffer,&DigitalO2ID); | |
560 /* no break */ | |
561 default: Comstatus_O2 = UART_O2_IDLE; | |
562 rxState = O2RX_IDLE; | |
563 break; | |
564 } | |
565 } | |
566 break; | |
567 default: rxState = O2RX_IDLE; | |
568 break; | |
569 | |
570 } | |
571 | |
572 localRX++; | |
573 rxReadIndex++; | |
574 if(rxReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) | |
575 { | |
576 localRX = 0; | |
577 rxReadIndex = 0; | |
578 } | |
579 } | |
580 | |
581 if(time_elapsed_ms(lastReceiveTick,HAL_GetTick()) > 4000) /* check for communication timeout */ | |
582 { | |
583 if(curAlive == lastAlive) | |
584 { | |
585 setExternalInterfaceChannel(0,0.0); | |
586 setExternalInterfaceChannel(1,0.0); | |
587 setExternalInterfaceChannel(2,0.0); | |
588 } | |
589 lastAlive = curAlive; | |
590 } | |
591 | |
592 if((dmaActive == 0) && (externalInterface_isEnabledPower33())) /* Should never happen in normal operation => restart in case of communication error */ | |
593 { | |
594 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) | |
595 { | |
596 dmaActive = 1; | |
597 } | |
598 } | |
599 } | |
600 | |
601 | |
359 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) | 602 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) |
360 { | 603 { |
361 if(huart == &huart1) | 604 if(huart == &huart1) |
362 { | 605 { |
363 dmaActive = 0; | 606 dmaActive = 0; |
368 } | 611 } |
369 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */ | 612 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) /* start next transfer if we did not catch up with read index */ |
370 { | 613 { |
371 if(externalInterface_isEnabledPower33()) | 614 if(externalInterface_isEnabledPower33()) |
372 { | 615 { |
616 memset((char*)&rxBuffer[rxWriteIndex],(int)0,CHUNK_SIZE); | |
373 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) | 617 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) |
374 { | 618 { |
375 dmaActive = 1; | 619 dmaActive = 1; |
376 } | 620 } |
377 } | 621 } |