cancel
Showing results for 
Search instead for 
Did you mean: 

stm32u575vgt, usart DMA rX , rx_buff was not changed by DMA.

simonkoo
Associate II

Post edited by ST moderator. In next time please use </> to share your code. Thank you for your understanding.

hi, I am using stm32U5's uasrt2 DMA RX ,  DMA interrupt coming, usart idle int coming, ROR value right, but rx_buffer was not refreshed by DMA, here is my part of code.

 
/* USER CODE BEGIN PV */
uint8_t loop_TX = 0xaa;
uint8_t loop_RX = 0x0f;
/* USER CODE END PV */
.............................


/* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* Reset of all peripherals, Initializes the Flash interface and the Systick.
   */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();
  /* GTZC initialisation */
  MX_GTZC_Init();

  /* USER CODE BEGIN SysInit */
  delay_init();
  HAL_Delay(100);
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_SPI2_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_UCPD1_Init();
  MX_I2C4_Init();
  MX_LPUART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_I2C3_Init();
  MX_FLASH_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  MX_ICACHE_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
 HAL_Delay(100);
while (1) {
    /* First transmit data, then start DMA receive */
    if (loop_TX < 0xFF) {
      loop_TX++;
      HAL_UART_Transmit(&huart2, &loop_TX, 1, 100);
      HAL_Delay(100);
      /* Start DMA receive with IDLE detection */
      HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &loop_RX, 1);
      /* Wait for DMA transfer to complete */
      HAL_Delay(500);
      /* Flush cache to ensure DMA data is visible to CPU */
      //SCB_InvalidateDCache_by_Addr(&loop_RX, sizeof(loop_RX));
      printf("[MAIN] TX: %02X, RX: %02X\r\n", loop_TX, loop_RX);
    }
  }
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) {
   
    __HAL_UART_CLEAR_IDLEFLAG(&huart2);

    uint16_t dma_cntr = __HAL_DMA_GET_COUNTER(huart2.hdmarx);
   
    /* Flush cache to ensure DMA data is visible to CPU */
    //SCB_InvalidateDCache_by_Addr(&loop_RX, sizeof(loop_RX));
   
    printf("[USART2] IDLE, DMA CNDTR=%u, RX=%02X, RDR=%02X\r\n",
           dma_cntr, loop_RX, huart2.Instance->RDR);
  }
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  /* USER CODE END USART2_IRQn 1 */
}
void GPDMA1_Channel4_IRQHandler(void)
{
  /* USER CODE BEGIN GPDMA1_Channel4_IRQn 0 */
  /* USER CODE END GPDMA1_Channel4_IRQn 0 */
  HAL_DMA_IRQHandler(&handle_GPDMA1_Channel4);
  /* USER CODE BEGIN GPDMA1_Channel4_IRQn 1 */
  printf("[GPDMA1_Channel4] DMA done, CNDTR=%u\r\n",
         __HAL_DMA_GET_COUNTER(&handle_GPDMA1_Channel4));
  printf(
      "[GPDMA1_Channel4] DMA buf: %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
      g_oas1200.rx_buffer[0], g_oas1200.rx_buffer[1], g_oas1200.rx_buffer[2],
      g_oas1200.rx_buffer[3], g_oas1200.rx_buffer[4], g_oas1200.rx_buffer[5],
      g_oas1200.rx_buffer[6], g_oas1200.rx_buffer[7]);

  /* USER CODE END GPDMA1_Channel4_IRQn 1 */
}

here is some print result :

[MAIN] loop_RX addr=0x20000029

[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000

[MAIN] TX: B4, RX: 0F

[USART2] IDLE, DMA CNDTR=0, RX=0F, RDR=B5

[MAIN] loop_RX addr=0x20000029

[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000

[MAIN] TX: B5, RX: 0F

[USART2] IDLE, DMA CNDTR=0, RX=0F, RDR=B6[MAIN] loop_RX addr=0x20000029

[GPDMA1_Channel0] DMA done, CNDTR=0, CSAR=0x40004424, CDAR=0x20000029, CTR1=0x00000000

 

10ebc053-ecce-41f0-8ab8-c576f4fc8c96.pngst.png

I connect usart2 TX and RX pin to do the test , the RX value should be  equal to TX, I have no idea what is wrong ....

1 ACCEPTED SOLUTION

Accepted Solutions
Gyessine
ST Employee

Hello @simonkoo 
Here are some ideas that might help you troubleshoot and solve your issue.
First, I noticed that you have

  MX_GTZC_Init();

Are you using the secure zone intentionally? If yes, verify that you handle it correctly. If it is not mandatory, consider using a nonsecure world project to simplify manipulation.

Second, do you really need all these peripherals?

MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_SPI2_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_UCPD1_Init();
  MX_I2C4_Init();
  MX_LPUART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_I2C3_Init();
  MX_FLASH_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  MX_ICACHE_Init();

If not, create a project with only the required peripherals, such as USART1 and GPDMA. Clear pinouts when the .ioc file opens.

-I also recommend enabling the destination address increment.

Finally, I have attached a project that echoes a "hello world" buffer transmitted through USART1_TX to USART1_RX using HAL_UART_Receive_DMA and prints it in a buffer named rx_buffer. You can visualize rx_buffer using live expression. Wire the TX pin to the RX pin. Use this project as a reference to identify issues in your project.

BR
Gyessine



To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

2 REPLIES 2
Gyessine
ST Employee

Hello @simonkoo 
Here are some ideas that might help you troubleshoot and solve your issue.
First, I noticed that you have

  MX_GTZC_Init();

Are you using the secure zone intentionally? If yes, verify that you handle it correctly. If it is not mandatory, consider using a nonsecure world project to simplify manipulation.

Second, do you really need all these peripherals?

MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_SPI2_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_UCPD1_Init();
  MX_I2C4_Init();
  MX_LPUART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_I2C3_Init();
  MX_FLASH_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  MX_ICACHE_Init();

If not, create a project with only the required peripherals, such as USART1 and GPDMA. Clear pinouts when the .ioc file opens.

-I also recommend enabling the destination address increment.

Finally, I have attached a project that echoes a "hello world" buffer transmitted through USART1_TX to USART1_RX using HAL_UART_Receive_DMA and prints it in a buffer named rx_buffer. You can visualize rx_buffer using live expression. Wire the TX pin to the RX pin. Use this project as a reference to identify issues in your project.

BR
Gyessine



To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

thanks a lot , it really was caused by  

  MX_GTZC_Init();

I used memory management tool in MX which set the GTZC enable 

Thanks !!!

 

BR

Simon