Skip to main content
CBrom.1
Associate II
April 1, 2021
Question

STM32H750 read USART Rx data via DMA

  • April 1, 2021
  • 0 replies
  • 1028 views

Dear ST Community,

I would like to set up the USART1 and DMA2 in a way, so that the DMA automatically stores the data received by the USART to a buffer variable.

To achieve that I used STM32CubeMX to generate the configuration code utilizing the Low Level- library and added some necessary commands.

Without DMA request enabled the USART1_IRQHandler is entered and via the debugger I can read the expected data within the USART1->RDR register. With the DMA request enabled neither the USART nor the DMA IRQHandler are accessed. Therefore, I suspect that my problem is that with the DMA Request enabled no interrupt is issued when sending data.

If you can find problems with my code I would really appreciate your answers.

The compiler otimization flag is set to -O0. The code is as follows:

 Declaration of the buffer variable:

__attribute__ ((section(".buffers"), used))
uint8_t usart1_rx_buffer[10];

with the key .buffers is mapped to the SRAM memory address 0x38000000 in the linker script according to https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices:

 .buffers(NOLOAD) : {
 . = ALIGN(4);
 *(.buffers*)
 } > RAM_D3

Commands within the main function:

 LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
 
 NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_USART1_UART_Init();
 
 while (1)
 {
	 __asm("nop");
 }

SystemClock_Config():

 LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
 while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_4)
 {
 }
 LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
 LL_RCC_HSI_Enable();
 
 /* Wait till HSI is ready */
 while(LL_RCC_HSI_IsReady() != 1)
 {
 
 }
 LL_RCC_HSI_SetCalibTrimming(32);
 LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV1);
 LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
 LL_RCC_PLL1P_Enable();
 LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
 LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
 LL_RCC_PLL1_SetM(4);
 LL_RCC_PLL1_SetN(60);
 LL_RCC_PLL1_SetP(2);
 LL_RCC_PLL1_SetQ(2);
 LL_RCC_PLL1_SetR(2);
 LL_RCC_PLL1_Enable();
 
 /* Wait till PLL is ready */
 while(LL_RCC_PLL1_IsReady() != 1)
 {
 }
 
 /* Intermediate AHB prescaler 2 when target frequency clock is higher than 80 MHz */
 LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
 
 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
 LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
 LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
 LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
 LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
 
 LL_Init1msTick(480000000);
 
 LL_SetSystemCoreClock(480000000);
 LL_RCC_SetUSARTClockSource(LL_RCC_USART16_CLKSOURCE_PCLK2);

MX_GPIO_Init():

/* GPIO Ports Clock Enable */
 LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);

 MX_DMA_Init():

/* DMA controller clock enable */
 LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
 
 NVIC_SetPriority(DMA2_Stream0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
 NVIC_EnableIRQ(DMA2_Stream0_IRQn);
 
 NVIC_SetPriority(DMA2_Stream1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
 NVIC_EnableIRQ(DMA2_Stream1_IRQn);

 MX_USART1_UART_Init():

 LL_USART_InitTypeDef USART_InitStruct = {0};
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 /* Peripheral clock enable */
 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
  LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
 
 /**USART1 GPIO Configuration
 PB14 ------> USART1_TX
 PB15 ------> USART1_RX */
 GPIO_InitStruct.Pin 			= LL_GPIO_PIN_14|LL_GPIO_PIN_15;
 GPIO_InitStruct.Mode 			= LL_GPIO_MODE_ALTERNATE;
 GPIO_InitStruct.Speed 		= LL_GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.OutputType 	= LL_GPIO_OUTPUT_PUSHPULL;
 GPIO_InitStruct.Pull 			= LL_GPIO_PULL_NO;
 GPIO_InitStruct.Alternate 	= LL_GPIO_AF_4;
 LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
 /* USART1 interrupt Init */
 NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
 NVIC_EnableIRQ(USART1_IRQn);
 
 USART_InitStruct.PrescalerValue 		= LL_USART_PRESCALER_DIV1;
 USART_InitStruct.BaudRate 			= 115200;
 USART_InitStruct.DataWidth 			= LL_USART_DATAWIDTH_8B;
 USART_InitStruct.StopBits 			= LL_USART_STOPBITS_1;
 USART_InitStruct.Parity 				= LL_USART_PARITY_NONE;
 USART_InitStruct.TransferDirection 	= LL_USART_DIRECTION_TX_RX;
 USART_InitStruct.HardwareFlowControl 	= LL_USART_HWCONTROL_NONE;
 USART_InitStruct.OverSampling 		= LL_USART_OVERSAMPLING_16;
 LL_USART_Init(USART1, &USART_InitStruct);
  
 LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2);
 LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2);
 LL_USART_DisableFIFO(USART1);
 
 LL_USART_ConfigAsyncMode(USART1);
 LL_USART_EnableDMAReq_RX(USART1);
 LL_USART_DisableOneBitSamp(USART1);
 LL_USART_DisableIT_TC(USART1);
 LL_USART_ClearFlag_TC(USART1);
 
 LL_USART_EnableIT_RXNE_RXFNE(USART1);
 LL_USART_Enable(USART1);
  /* Polling USART1 initialisation */
 while((!(LL_USART_IsActiveFlag_REACK(USART1))))
 {
 }
 
 /* USART1_RX Init */
  LL_DMA_SetPeriphRequest(DMA2, LL_DMA_STREAM_0, LL_DMAMUX1_REQ_USART1_RX);
 LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
 LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_0, LL_DMA_PRIORITY_LOW);
 LL_DMA_SetMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MODE_CIRCULAR);
 LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);
 LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT);
 LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_BYTE);
 LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_BYTE);
 LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_0);
 
 /* USART1_TX Init */
 LL_DMA_SetPeriphRequest(DMA2, LL_DMA_STREAM_1, LL_DMAMUX1_REQ_USART1_TX);
 LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_1, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
 LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_1, LL_DMA_PRIORITY_LOW);
 LL_DMA_SetMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MODE_NORMAL);
 LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT);
 LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT);
 LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_BYTE);
 LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_BYTE);
 LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_1);
 
 LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_0, (uint32_t)(&(USART1->RDR)));
 LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_0, (uint32_t)(&usart1_rx_buffer));
 LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_0, 4);
 LL_DMA_SetMemoryBurstxfer(DMA2, LL_DMA_STREAM_0, LL_DMA_MBURST_SINGLE);
 LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_0, LL_DMA_PRIORITY_HIGH);
 LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_0);
 LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_0);
 
 LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_1, (uint32_t)(&(USART1->TDR)));
 LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_1, (uint32_t)(&usart1_tx_buffer));
 LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_1, 1);
 LL_DMA_SetMemoryBurstxfer(DMA2, LL_DMA_STREAM_1, LL_DMA_MBURST_SINGLE);
 LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_1);
 LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_1);
 
 LL_USART_DisableDirectionTx(USART1);
 LL_USART_EnableDirectionRx(USART1);

USART1_IRQHandler():

if(LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) 
 LL_USART_ClearFlag_NE(USART1);
 if(LL_USART_IsActiveFlag_FE(USART1))
 LL_USART_ClearFlag_FE(USART1);
 if(LL_USART_IsActiveFlag_ORE(USART1))
 LL_USART_ClearFlag_ORE(USART1);
 if(LL_USART_IsActiveFlag_TC(USART1))
 LL_USART_ClearFlag_TC(USART1);

 DMA2_Stream0_IRQHandler():

if(LL_DMA_IsActiveFlag_HT0(DMA2))
 LL_DMA_ClearFlag_HT0(DMA2);
 if(LL_DMA_IsActiveFlag_TC0(DMA2))
 LL_DMA_ClearFlag_TC0(DMA2);

DMA2_Stream1_IRQHandler():

if(LL_DMA_IsActiveFlag_HT1(DMA2))
 LL_DMA_ClearFlag_HT1(DMA2);
 if(LL_DMA_IsActiveFlag_TC1(DMA2))
 LL_DMA_ClearFlag_TC1(DMA2);

This topic has been closed for replies.