cancel
Showing results for 
Search instead for 
Did you mean: 

2 STM32F407 sending data to each other using DMA

ToasterOvenDan
Associate II

I have 2 STM32F407 Discovery boards sending data back and forth to each other using usart2. Usart3 on one is just a monitor so I can see the output on a USB comm port. I'm using DMA on the receive for both and the HAL_UART_RxCpltCallback for both just sends the data back for both boards. I have to have a transmit in one of the tasks before it will work. I have a counter that advances in each callback that spins the 4 LED's so I can see if it's working because it goes too fast to spit it out to the comm port. Is there any way to slow it down? I tried putting a vTaskDelay in one of the callbacks but I don't think you can do that. I'm using STM32CubeIDE and FreeRTOS.I have attached both freertos.c files from the Core/Src/ directory. The lights spin incredibly fast and then slow down and pause once in a while.

1 ACCEPTED SOLUTION

Accepted Solutions
Karl Yamashita
Principal

Set a flag in HAL_UART_RxCpltCallback and check the flag in a task. In the task you can use a delay instead of using the delay in the interrupt. In the same task you can transmit instead of transmitting in the interrupt with blocking transmit.

 

volatile bool dataRdy = false; void StartTask03(void const * argument) { /* USER CODE BEGIN StartTask03 */ /* Infinite loop */ // 57FF70064983574811332087 id of ST-Link for test_uart3 // 066EFF565257867767140832 id of ST-Link for test_uart2 vTaskDelay(10); HAL_UART_Receive_DMA (&huart2, &data[0], DATA_SIZE); for(;;) { vTaskDelay(2000); if(dataRdy) { dataRdy = 0; HAL_UART_Transmit(&huart2, &data[0], DATA_SIZE, 10); } } /* USER CODE END StartTask03 */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { //HAL_UART_Transmit(&huart3, data, 10, 200); HAL_UART_Receive_DMA(&huart2, &data[0], DATA_SIZE); dataRdy = true //HAL_UART_Transmit(&huart3, &data[0], DATA_SIZE, 1000); //HAL_UART_Transmit(&huart3, &crlf[0], 2, 10); //vTaskDelay(1000); if(++menu_ptr > 3) menu_ptr = 0; }
View more
Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.

View solution in original post

3 REPLIES 3
ToasterOvenDan
Associate II

looking through stm32f4xx_hal_uart.h I found HAL_UART_DMAPause() and HAL_UART_DMAResume(). I guess I'll try that.

Karl Yamashita
Principal

Set a flag in HAL_UART_RxCpltCallback and check the flag in a task. In the task you can use a delay instead of using the delay in the interrupt. In the same task you can transmit instead of transmitting in the interrupt with blocking transmit.

 

volatile bool dataRdy = false; void StartTask03(void const * argument) { /* USER CODE BEGIN StartTask03 */ /* Infinite loop */ // 57FF70064983574811332087 id of ST-Link for test_uart3 // 066EFF565257867767140832 id of ST-Link for test_uart2 vTaskDelay(10); HAL_UART_Receive_DMA (&huart2, &data[0], DATA_SIZE); for(;;) { vTaskDelay(2000); if(dataRdy) { dataRdy = 0; HAL_UART_Transmit(&huart2, &data[0], DATA_SIZE, 10); } } /* USER CODE END StartTask03 */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { //HAL_UART_Transmit(&huart3, data, 10, 200); HAL_UART_Receive_DMA(&huart2, &data[0], DATA_SIZE); dataRdy = true //HAL_UART_Transmit(&huart3, &data[0], DATA_SIZE, 1000); //HAL_UART_Transmit(&huart3, &crlf[0], 2, 10); //vTaskDelay(1000); if(++menu_ptr > 3) menu_ptr = 0; }
View more
Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.
Carl_G
Senior

Have you tried lowering the BAUD rate?