Mercurial > public > ostc4
comparison Small_CPU/Src/uart.c @ 918:f72613a152dd Evo_2_23
Switch external interface tx communication to DMA:
In the previous version the transmitting of data was done in polling mode. With the introduction of new sensors the length of commands send to the sensor may increase and have a impact to the runtim behavior of the SW. To avoid this the DMA transfers for TX has been activated.
| author | Ideenmodellierer |
|---|---|
| date | Sun, 03 Nov 2024 15:40:55 +0100 |
| parents | 4832981f9af8 |
| children | eb4109d7d1e9 |
comparison
equal
deleted
inserted
replaced
| 917:0d6c4b40fae4 | 918:f72613a152dd |
|---|---|
| 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 "uartProtocol_Co2.h" |
| 25 #include "uartProtocol_Sentinel.h" | 25 #include "uartProtocol_Sentinel.h" |
| 26 #include "uartProtocol_GNSS.h" | |
| 26 #include "externalInterface.h" | 27 #include "externalInterface.h" |
| 27 #include "data_exchange.h" | 28 #include "data_exchange.h" |
| 28 #include <string.h> /* memset */ | 29 #include <string.h> /* memset */ |
| 29 | 30 |
| 30 | 31 |
| 31 /* Private variables ---------------------------------------------------------*/ | 32 /* Private variables ---------------------------------------------------------*/ |
| 32 | 33 |
| 33 | 34 |
| 34 | 35 #define TX_BUF_SIZE (40u) /* max length for commands */ |
| 35 #define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ | 36 #define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ |
| 36 #define CHUNKS_PER_BUFFER (5u) | 37 #define CHUNKS_PER_BUFFER (6u) |
| 37 | 38 |
| 38 | 39 |
| 39 | 40 |
| 40 DMA_HandleTypeDef hdma_usart1_rx, hdma_usart1_tx, hdma_usart6_rx, hdma_usart6_tx; | 41 DMA_HandleTypeDef hdma_usart1_rx, hdma_usart1_tx, hdma_usart6_rx, hdma_usart6_tx; |
| 41 | 42 |
| 42 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ | 43 uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ |
| 43 uint8_t txBuffer[CHUNK_SIZE]; /* tx uses less bytes */ | 44 uint8_t txBuffer[CHUNK_SIZE]; /* tx uses less bytes */ |
| 44 uint8_t txBufferQue[CHUNK_SIZE]; /* In MUX mode command may be send shortly after each other => allow q 1 entry que */ | 45 uint8_t txBufferQue[TX_BUF_SIZE]; /* In MUX mode command may be send shortly after each other => allow q 1 entry que */ |
| 45 uint8_t txBufferQueLen; | 46 uint8_t txBufferQueLen; |
| 46 | 47 |
| 47 uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ | 48 uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ |
| 48 uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ | 49 uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ |
| 49 | 50 |
| 52 static uint8_t lastCmdIndex; /* Index of last command which has not been completely received */ | 53 static uint8_t lastCmdIndex; /* Index of last command which has not been completely received */ |
| 53 static uint8_t dmaRxActive; /* Indicator if DMA reception needs to be started */ | 54 static uint8_t dmaRxActive; /* Indicator if DMA reception needs to be started */ |
| 54 static uint8_t dmaTxActive; /* Indicator if DMA reception needs to be started */ | 55 static uint8_t dmaTxActive; /* Indicator if DMA reception needs to be started */ |
| 55 | 56 |
| 56 | 57 |
| 57 | 58 static uint8_t isEndIndication(uint8_t index); |
| 58 | 59 |
| 59 /* Exported functions --------------------------------------------------------*/ | 60 /* Exported functions --------------------------------------------------------*/ |
| 60 | 61 |
| 61 void clearRxBuffer(void) | 62 void UART_clearRxBuffer(void) |
| 62 { | 63 { |
| 63 uint16_t index = 0; | 64 uint16_t index = 0; |
| 64 do | 65 do |
| 65 { | 66 { |
| 66 rxBuffer[index++] = BUFFER_NODATA_LOW; | 67 rxBuffer[index++] = BUFFER_NODATA_LOW; |
| 67 rxBuffer[index++] = BUFFER_NODATA_HIGH; | 68 rxBuffer[index++] = BUFFER_NODATA_HIGH; |
| 68 } while (index < sizeof(rxBuffer)); | 69 } while (index < sizeof(rxBuffer)); |
| 70 | |
| 71 rxReadIndex = 0; | |
| 72 rxWriteIndex = 0; | |
| 69 } | 73 } |
| 70 | 74 |
| 71 void MX_USART1_UART_Init(void) | 75 void MX_USART1_UART_Init(void) |
| 72 { | 76 { |
| 73 /* regular init */ | 77 /* regular init */ |
| 82 | 86 |
| 83 HAL_UART_Init(&huart1); | 87 HAL_UART_Init(&huart1); |
| 84 | 88 |
| 85 MX_USART1_DMA_Init(); | 89 MX_USART1_DMA_Init(); |
| 86 | 90 |
| 87 HAL_NVIC_SetPriority(USART1_IRQn, 1, 3); | 91 UART_clearRxBuffer(); |
| 88 HAL_NVIC_EnableIRQ(USART1_IRQn); | |
| 89 | |
| 90 clearRxBuffer(); | |
| 91 rxReadIndex = 0; | 92 rxReadIndex = 0; |
| 92 lastCmdIndex = 0; | 93 lastCmdIndex = 0; |
| 93 rxWriteIndex = 0; | 94 rxWriteIndex = 0; |
| 94 dmaRxActive = 0; | 95 dmaRxActive = 0; |
| 95 dmaTxActive = 0; | 96 dmaTxActive = 0; |
| 284 { | 285 { |
| 285 uint8_t cmdLength = strlen((char*)cmdString); | 286 uint8_t cmdLength = strlen((char*)cmdString); |
| 286 | 287 |
| 287 if(dmaTxActive == 0) | 288 if(dmaTxActive == 0) |
| 288 { | 289 { |
| 289 if(cmdLength < CHUNK_SIZE) /* A longer string is an indication for a missing 0 termination */ | 290 if(cmdLength < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */ |
| 290 { | 291 { |
| 291 if(dmaRxActive == 0) | 292 if(dmaRxActive == 0) |
| 292 { | 293 { |
| 293 UART_StartDMA_Receiption(); | 294 UART_StartDMA_Receiption(); |
| 294 } | 295 } |
| 306 } | 307 } |
| 307 } | 308 } |
| 308 | 309 |
| 309 void UART_SendCmdUbx(uint8_t *cmd, uint8_t len) | 310 void UART_SendCmdUbx(uint8_t *cmd, uint8_t len) |
| 310 { | 311 { |
| 311 if(len < CHUNK_SIZE) /* A longer string is an indication for a missing 0 termination */ | 312 if(len < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */ |
| 312 { | 313 { |
| 313 if(dmaRxActive == 0) | 314 if(dmaRxActive == 0) |
| 314 { | 315 { |
| 315 UART_StartDMA_Receiption(); | 316 UART_StartDMA_Receiption(); |
| 316 } | 317 } |
| 317 memcpy(txBuffer, cmd, len); | 318 memcpy(txBuffer, cmd, len); |
| 318 HAL_UART_Transmit_DMA(&huart1,txBuffer,len); | 319 if(HAL_OK == HAL_UART_Transmit_DMA(&huart1,txBuffer,len)) |
| 320 { | |
| 321 dmaTxActive = 1; | |
| 322 } | |
| 319 } | 323 } |
| 320 } | 324 } |
| 321 | 325 |
| 322 | 326 |
| 323 void StringToInt(char *pstr, uint32_t *puInt32) | 327 void StringToInt(char *pstr, uint32_t *puInt32) |
| 348 | 352 |
| 349 void UART_StartDMA_Receiption() | 353 void UART_StartDMA_Receiption() |
| 350 { | 354 { |
| 351 if(dmaRxActive == 0) | 355 if(dmaRxActive == 0) |
| 352 { | 356 { |
| 353 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) | 357 if(((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE)) || ((isEndIndication(rxWriteIndex)) && (isEndIndication(rxWriteIndex + 1)))) /* start next transfer if we did not catch up with read index */ |
| 354 { | 358 { |
| 355 dmaRxActive = 1; | 359 if(HAL_OK == HAL_UART_Receive_DMA (&huart1, &rxBuffer[rxWriteIndex], CHUNK_SIZE)) |
| 356 } | 360 { |
| 361 dmaRxActive = 1; | |
| 362 } | |
| 363 } | |
| 357 } | 364 } |
| 358 } | 365 } |
| 359 | 366 |
| 360 void UART_ChangeBaudrate(uint32_t newBaudrate) | 367 void UART_ChangeBaudrate(uint32_t newBaudrate) |
| 361 { | 368 { |
| 362 uint8_t dmaWasActive = dmaRxActive; | 369 MX_USART1_UART_DeInit(); |
| 363 // HAL_DMA_Abort(&hdma_usart1_rx); | |
| 364 MX_USART1_UART_DeInit(); | |
| 365 //HAL_UART_Abort(&huart1); | |
| 366 //HAL_DMA_DeInit(&hdma_usart1_rx); | |
| 367 | |
| 368 | |
| 369 // huart1.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq()/2, newBaudrate); | |
| 370 huart1.Init.BaudRate = newBaudrate; | 370 huart1.Init.BaudRate = newBaudrate; |
| 371 HAL_UART_Init(&huart1); | 371 HAL_UART_Init(&huart1); |
| 372 MX_USART1_DMA_Init(); | 372 MX_USART1_DMA_Init(); |
| 373 HAL_NVIC_SetPriority(USART1_IRQn, 1, 3); | 373 HAL_NVIC_SetPriority(USART1_IRQn, 1, 3); |
| 374 HAL_NVIC_EnableIRQ(USART1_IRQn); | 374 HAL_NVIC_EnableIRQ(USART1_IRQn); |
| 375 | 375 |
| 376 if(dmaWasActive) | 376 UART_clearRxBuffer(); |
| 377 { | 377 rxReadIndex = 0; |
| 378 clearRxBuffer(); | 378 rxWriteIndex = 0; |
| 379 rxReadIndex = 0; | 379 dmaRxActive = 0; |
| 380 rxWriteIndex = 0; | 380 txBufferQueLen = 0; |
| 381 dmaRxActive = 0; | |
| 382 txBufferQueLen = 0; | |
| 383 UART_StartDMA_Receiption(); | |
| 384 } | |
| 385 } | 381 } |
| 386 | 382 |
| 387 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) | 383 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) |
| 388 { | 384 { |
| 389 if(huart == &huart1) | 385 if(huart == &huart1) |
| 392 rxWriteIndex+=CHUNK_SIZE; | 388 rxWriteIndex+=CHUNK_SIZE; |
| 393 if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) | 389 if(rxWriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) |
| 394 { | 390 { |
| 395 rxWriteIndex = 0; | 391 rxWriteIndex = 0; |
| 396 } | 392 } |
| 397 if((rxWriteIndex / CHUNK_SIZE) != (rxReadIndex / CHUNK_SIZE) || (rxWriteIndex == rxReadIndex)) /* start next transfer if we did not catch up with read index */ | 393 UART_StartDMA_Receiption(); |
| 398 { | |
| 399 UART_StartDMA_Receiption(); | |
| 400 } | |
| 401 } | 394 } |
| 402 } | 395 } |
| 403 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) | 396 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) |
| 404 { | 397 { |
| 405 if(huart == &huart1) | 398 if(huart == &huart1) |
| 506 if(huart1.hdmatx->State == HAL_DMA_STATE_READY) | 499 if(huart1.hdmatx->State == HAL_DMA_STATE_READY) |
| 507 { | 500 { |
| 508 huart1.gState = HAL_UART_STATE_READY; | 501 huart1.gState = HAL_UART_STATE_READY; |
| 509 dmaTxActive = 0; | 502 dmaTxActive = 0; |
| 510 } | 503 } |
| 504 if(huart1.hdmarx->State == HAL_DMA_STATE_READY) | |
| 505 { | |
| 506 huart1.RxState = HAL_UART_STATE_READY; | |
| 507 dmaRxActive = 0; | |
| 508 } | |
| 511 } | 509 } |
| 512 | 510 |
| 513 void UART_FlushRxBuffer(void) | 511 void UART_FlushRxBuffer(void) |
| 514 { | 512 { |
| 515 uint8_t futureIndex = rxReadIndex + 1; | 513 uint8_t futureIndex = rxReadIndex + 1; |
