cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G4 RX DMA not working

char_array
Associate III

I tested the sending with a USB-serial converter and I can see the MCU is sending. Looping back the TX signal to the RX on the board doesn't result in receiving data, nor does connecting the TX of the USB-serial converter. However I do get RX line error interrupts if I connect the wire, and if I enable idle line interrupt that works too.

Here is my stripped down code:

#include "app_main.h"
 
#include "main.h" // includes correct STM32 HAL
 
//RTOS includes
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os2.h"
 
#include <stdio.h>
#include  <sys/unistd.h>
 
#ifdef DEBUG
 
extern "C" int _write(int file, char* data, int size)
{
    if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
    {
        return -1;
    }
 
    for(int i = 0; i < size; ++i)
    {
        ITM_SendChar(data[i]);
    }
 
    return size;
}
#endif
 
static TaskHandle_t appMainTaskHandle;
static constexpr UBaseType_t APP_MAIN_TASK_PRIORITY = ( UBaseType_t ) (osPriorityNormal) ;
static constexpr size_t APP_MAIN_TASK_STACK_SIZE_BYTES = 2048;
 
extern UART_HandleTypeDef huart1;
 
/*
USART1:
PC4 TX
PC5 RX
*/
 
static void uartTestTask(void* arg)
{
    constexpr size_t m_BUFFER_SIZE = 50;
    uint8_t m_rxBuffer[m_BUFFER_SIZE];
 
    const uint8_t* m_rxTail;
 
    UART_HandleTypeDef* const m_pUartHandle = &huart1;
 
    m_rxTail = m_rxBuffer; // reset buffer
    HAL_UART_Receive_DMA(m_pUartHandle, (uint8_t*)m_rxBuffer, m_BUFFER_SIZE); // start DMA reception
 
    while(1)
    {
 
        size_t len;
 
        const uint8_t* rxHead =  m_rxBuffer + m_BUFFER_SIZE - m_pUartHandle->hdmarx->Instance->CNDTR;
 
        if (rxHead >= m_rxTail)
        {
            len = rxHead - m_rxTail;
        }
        else
        {
            len = rxHead - m_rxTail + m_BUFFER_SIZE;
        }
 
        printf("len: %d\n", len);
 
        HAL_UART_Transmit(m_pUartHandle, (uint8_t*)"test\n", 5, 1000);
 
        vTaskDelay(1000 / portTICK_PERIOD_MS); //startup delay
    }
}
 
 
static void appMainTask(void* arg)
{
    vTaskDelay(10 / portTICK_PERIOD_MS); //startup delay
 
    [[maybe_unused]] BaseType_t res = 
        xTaskCreate(
            uartTestTask,
            "uartTestTask",
            APP_MAIN_TASK_STACK_SIZE_BYTES/4,
            NULL,
            APP_MAIN_TASK_PRIORITY,
            NULL );
 
 
    while(1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
 
extern "C" bool startAppMainTask()
{
    BaseType_t res = xTaskCreate(   appMainTask,
                                    "appMain",
                                    APP_MAIN_TASK_STACK_SIZE_BYTES/4,
                                    NULL,
                                    APP_MAIN_TASK_PRIORITY,
                                    &appMainTaskHandle );
    return res == pdPASS;
}

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru
2 REPLIES 2
char_array
Associate III

I found the answer. STM32CubeMX initialized the DMA after the UART. It needs to be initialized before the UART.

I will check if a newer version of CubeMX fixed the bug.

TDK
Guru

https://community.st.com/s/question/0D53W00001EzCmCSAV/mxdmainit-order-in-the-mainc-file-generated-by-stm32cubemx-how-to-fix

If you feel a post has answered your question, please click "Accept as Solution".