2025-03-28 8:19 AM - last edited on 2025-03-28 10:20 AM by mƎALLEm
Hello, I'm trying to use the HPDMA1 with channel 0 to transfer the data from UART1 to AXIRAM5 (from 0x342E0000).
I want to receive all the data (about 150KB) from the UART through DMA at once (it can only transfer 64KB at once because of the limited block size). so I used the Linked list mode to move things in 3 nodes.
However, it doesn't work, every time I start my DMA, it goes to user setting error flag.
Here is my linked list.c file
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : linked_list.c
* Description : This file provides code for the configuration
* of the LinkedList.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "linked_list.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
DMA_NodeTypeDef First_block __NON_CACHEABLE;
DMA_QListTypeDef UART_Receive_Large_Data;
DMA_NodeTypeDef Second_block __NON_CACHEABLE;
DMA_NodeTypeDef Last_Bytes __NON_CACHEABLE;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/**
* @brief DMA Linked-list UART_Receive_Large_Data configuration
* @PAram None
* @retval None
*/
HAL_StatusTypeDef MX_UART_Receive_Large_Data_Config(void)
{
HAL_StatusTypeDef ret = HAL_OK;
/* DMA node configuration declaration */
DMA_NodeConfTypeDef pNodeConfig;
/* Set node configuration ################################################*/
pNodeConfig.NodeType = DMA_HPDMA_LINEAR_NODE;
pNodeConfig.Init.Request = HPDMA1_REQUEST_USART1_RX;
pNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
pNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
pNodeConfig.Init.SrcInc = DMA_SINC_FIXED;
pNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
pNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
pNodeConfig.Init.SrcBurstLength = 1;
pNodeConfig.Init.DestBurstLength = 1;
pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
pNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
pNodeConfig.Init.Mode = DMA_NORMAL;
pNodeConfig.RepeatBlockConfig.RepeatCount = 1;
pNodeConfig.RepeatBlockConfig.SrcAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.DestAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.BlkSrcAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.BlkDestAddrOffset = 0;
pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
pNodeConfig.SrcAddress = (uint32_t)&USART1->RDR;
pNodeConfig.DstAddress = 0x342E0000;
pNodeConfig.DataSize = 65535;
pNodeConfig.SrcSecure = DMA_CHANNEL_SRC_SEC;
pNodeConfig.DestSecure = DMA_CHANNEL_DEST_SEC;
/* Build First_block Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &First_block);
/* Insert First_block to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&UART_Receive_Large_Data, &First_block);
/* Set node configuration ################################################*/
pNodeConfig.DstAddress = (0x342E0000 + 65535);
/* Build Second_block Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &Second_block);
/* Insert Second_block to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&UART_Receive_Large_Data, &Second_block);
/* Set node configuration ################################################*/
pNodeConfig.DstAddress = (0x342E0000 + 65535 + 65535);
pNodeConfig.DataSize = 19458;
/* Build Last_Bytes Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &Last_Bytes);
/* Insert Last_Bytes to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&UART_Receive_Large_Data, &Last_Bytes);
return ret;
}
And this is my main()
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
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_HPDMA1_Init();
NPURam_enable();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
// try whether the RAM is able to write
// memcpy((void*)0x342E0000, &hi, 1);
MX_UART_Receive_Large_Data_Config();
HAL_DMAEx_List_LinkQ(&handle_HPDMA1_Channel0, &UART_Receive_Large_Data);
HAL_DMA_RegisterCallback(&handle_HPDMA1_Channel0, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);
HAL_DMA_RegisterCallback(&handle_HPDMA1_Channel0, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
HAL_DMAEx_List_Start_IT(&handle_HPDMA1_Channel0);
// HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(USART1_IRQn);
ATOMIC_SET_BIT(huart1.Instance->CR3, USART_CR3_DMAR);
__HAL_UART_ENABLE(&huart1);
// while (!dma_done_flag)
// {
// HAL_Delay(10);
// }
while ((TransferCompleteDetected == 0) && (TransferErrorDetected == 0U));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
char dma_done_msg[] = "DMA Transfer Finished\r\n";
HAL_UART_Transmit(&huart1, (uint8_t *)dma_done_msg, sizeof(dma_done_msg) - 1, HAL_MAX_DELAY);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
This is a photo of my debugging:
Inside HAL_DMAEx_List_Start_IT(DMA_HandleTypeDef *const hdma),
everything is working similar to Linked mode examples, right side is the registers
After the line: __HAL_DMA_ENABLE(hdma);It seems that the User setting error is arosed and then, all the registers are set to default.
I checked the User manual for many times, and did a lot of debugging, but never figure out whats going on.
Could you please help me figure out whats wrong with this? Thank you.
2025-03-28 10:22 AM
Hello,
Please kindly use </> button to paste your code. I've edited your post.
Please refer to this link.
2025-03-31 12:50 AM
Thank you very much for your help. However, I still haven't been able to fix this issue — the Linked List mode simply doesn't work in my case.
I've searched through many posts but couldn't find any similar problems, and honestly, I'm not sure what to try next.
I would really appreciate it if someone from ST could provide some guidance or suggestions.
Any help would be highly appreciated!