STM32 Printf UART does not wait for transmission to complete
Hi, I am trying to implement printf with UART using DMA. The problem is when i use consecutive printf's in my code, transmission of the first data is not being waited. I implemented a control block to check if the transmission is completed but it does not work. At first, i wrote this control block by changing dmi.sending flag. It did not work, so i decided to get the state directly from huart. It did not work either. When i debug the code and add breakpoint to
HAL_UART_Transmit_DMA(dmi.huart, (uint8_t*) ptr, len);
then the execution is successfull. I can see "123456\ntest\n" in the terminal. But when i stop debugging and run the code, i get this in the terminal:
1est
6
test
test
test
Why i can't control if the data is transmitted yet or not?
Here is my code
uart_write.c:
#include <ring_buffer.h>
#include "main.h"
#include <stdbool.h>
#include <uart_write.h>
struct dma_printf_info dmi;
void dma_printf_init(UART_HandleTypeDef *printf_huart) {
dmi.huart = printf_huart;
ring_init(&dmi.tx_ring);
dmi.sending = false;
}
void dma_printf_putc(char *ptr, int len) {
if (dmi.sending == false && ring_filled_space(&dmi.tx_ring) == 0) {
dmi.sending = true;
HAL_UART_Transmit_DMA(dmi.huart, (uint8_t*) ptr, len);
} else {
if (ring_empty_space(&dmi.tx_ring) >= len) {
for (int i = 0; i < len; i++)
ring_push(&dmi.tx_ring, ptr[i]);
} else { //BUF OVFL
while (1)
;
}
}
}
void dma_printf_send_it(UART_HandleTypeDef *printf_huart) {
if (dmi.huart != printf_huart) return;
if (ring_filled_space(&dmi.tx_ring) > 0) {
HAL_UART_Transmit_DMA(dmi.huart, (uint8_t*) dmi.tx_ring.buf, ring_filled_space(&dmi.tx_ring));
ring_empty_out(&dmi.tx_ring);
} else dmi.sending = false;
}
uart_write.h
#ifndef HAL_DMA_PRINTF_DMA_PRINTF_H
#define HAL_DMA_PRINTF_DMA_PRINTF_H
#include <ring_buffer.h>
#include "main.h"
struct dma_printf_info {
struct dma_ring_buf tx_ring;
volatile int sending;
UART_HandleTypeDef *huart;
};
void dma_printf_init(UART_HandleTypeDef *printf_huart);
void dma_printf_putc(char* ptr, int len);
void dma_printf_send_it(UART_HandleTypeDef *printf_huart);
#endif //HAL_DMA_PRINTF_DMA_PRINTF_H
main.c
/* USER CODE BEGIN 0 */
int _write(int file, char *ptr, int len) {
dma_printf_putc(ptr, len);
return len;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
dma_printf_send_it(huart);
}
/* USER CODE END 0 */
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_UART4_Init();
/* USER CODE BEGIN 2 */
dma_printf_init(&huart4);
dma_scanf_init(&huart4);
printf("123456\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
printf("test\n");
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
