STM32 DMA is not restarting when used with CMSIS V2 Queue

74 views Asked by At

I am developing STM32 firmware based on FreeRTOS. I am using Nucleo-G491RE board.

I am using CMSIS V2 and Queue to handle the data received on UART. The UART fires correctly on receipt of data and sends data to queue. The Queue handler task is receiving the data and processing the same.

The DMA not restarting after processing the first interrupt.

Here is the code handling the UART interrupt.

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart->Instance == UART5)
    {
        char buffer[3]; // Buffer to hold the formatted hex byte (2 characters) plus null terminator

        for (uint8_t i = 0; i < Size; i++) {
            sprintf(buffer, "%02X", RemoteRxBuf[i]); // Format the hex byte
            HAL_UART_Transmit(&hlpuart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
            HAL_UART_Transmit(&hlpuart1, (uint8_t*)" ", 1, HAL_MAX_DELAY); // Add space between hex bytes
        }

        HAL_UART_Transmit(&hlpuart1, (uint8_t*)"\r\n", 2, HAL_MAX_DELAY); // Newline at the end

        remote_cmd_t *remote_cmd = (remote_cmd_t *)malloc(sizeof(remote_cmd_t));
        // remote_cmd = pvPortMalloc(sizeof(remote_cmd_t));

        remote_cmd->Count = 1000;
        remote_cmd->Size = 5;
        memcpy(remote_cmd->Payload, RemoteRxBuf, 5);

        // Notify the task that new data is available
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;

        // Send the received data to the remoteQueueHandle
        xQueueSendFromISR(remoteQueueHandle, &remote_cmd, &xHigherPriorityTaskWoken);

        // If sending to the queue caused a task switch, request a context switch
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

        HAL_UARTEx_ReceiveToIdle_DMA(&huart5, RemoteRxBuf, RemoteRxBuf_SIZE);
        __HAL_DMA_DISABLE_IT(&hdma_uart5_rx, DMA_IT_HT);
    }
}

The following is the code of task processing the queue

void StartRemoteCmdTask(void *argument)
{
    /* USER CODE BEGIN 5 */
    char *buffer;
    remote_cmd_t *receivedData;
    /* Infinite loop */
    while(1)
    {
        if(xQueueReceive(remoteQueueHandle, &receivedData, portMAX_DELAY) == pdPASS)
        {
            char *msg = "Received data from ISR\r\r";
            HAL_UART_Transmit(&hlpuart1, (uint8_t *)msg, strlen(msg), 1000);
            buffer = pvPortMalloc(3 * sizeof(char));
            for (uint8_t i = 0; i < receivedData->Size; i++)
            {
                sprintf(buffer, "%02X", receivedData->Payload[i]);
                HAL_UART_Transmit(&hlpuart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
                HAL_UART_Transmit(&hlpuart1, (uint8_t*)" ", 1, HAL_MAX_DELAY);
            }
            HAL_UART_Transmit(&hlpuart1, (uint8_t*)"\r\n", 2, HAL_MAX_DELAY);
            vPortFree(buffer);
        }

        vPortFree(receivedData);

        vTaskDelay(100);
    }
    /* USER CODE END 5 */
}
0

There are 0 answers