cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 UART DMA idle interrupt

QingFeng
Associate II

hello

 when i use UART Idle interupt with DMA on STM32H743XIH6 chip,i found ,the interupt function will run imediatly when  HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *)Uart2RxBuffer, 50)run,and this is my core code

 
MPU_Config();
//  SCB_EnableICache();
//  SCB_EnableDCache();

HAL_Init();

SystemClock_Config();
PeriphCommonClock_Config();
delay_init();

__HAL_RCC_BKPRAM_CLK_ENABLE();
HAL_PWR_EnableBkUpAccess();

MX_GPIO_Init();
User_GPIO_Init();
MX_DMA_Init();

MX_USART2_UART_Init();
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *)Uart2RxBuffer, 50);

///////////////////////////////////////////////////////////////////////////
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;

/* USART2 init function */
void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler(__LINE__,__FILE__);
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler(__LINE__,__FILE__);
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler(__LINE__,__FILE__);
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler(__LINE__,__FILE__);
  }
  /* USER CODE BEGIN USART2_Init 2 */
  /* USER CODE END USART2_Init 2 */
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(uartHandle->Instance==USART2)
  {
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;
    PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler(__LINE__,__FILE__);
    }

    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();

    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PD5     ------> USART2_TX
    PD6     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/* USART2 DMA Init */
    /* USART2_RX Init */
    hdma_usart2_rx.Instance = DMA1_Stream6;
    hdma_usart2_rx.Init.Request = DMA_REQUEST_USART2_RX;
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
    {
      Error_Handler(__LINE__,__FILE__);
    }
    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);

HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
  if(uartHandle->Instance==USART2)
  {
    __HAL_RCC_USART2_CLK_DISABLE();

    /**USART2 GPIO Configuration
    PD5     ------> USART2_TX
    PD6     ------> USART2_RX
    */
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_5|GPIO_PIN_6);
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_NVIC_DisableIRQ(USART2_IRQn);
  }
}

extern volatile uint8_t Uart2RxBuffer[50];

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
  if(huart->Instance==USART2)
{
if(HAL_UART_RXEVENT_IDLE == HAL_UARTEx_GetRxEventType(huart))
{
printf("HAL_UART2_RXEVENT_IDLE:\r\n");
}
printf("HAL_UART2Ex_RxEventCallback:\r\n");
for(uint8_t i=0;i<50;i++)
{
printf("%c",Uart2RxBuffer[i]);
}
printf("(%d)\r\n",Size);
}
}

QingFeng_0-1762530510770.png

 

when power on or reset,the code that

HAL_UART2_RXEVENT_IDLE:
HAL_UART2Ex_RxEventCallback:
(50)

happen,and then i send "123456789"many times,it runs normal,why chip power on or reset it interupt imediatly,and size equals to HAL_UARTEx_ReceiveToIdle_DMA config size


Edited to apply source code formatting - please see How to insert source code for future reference.

3 REPLIES 3
TDK
Super User

It doesn't do this for me with a clean project, default settings, using the latest library.

Try using a weak pullup on the RX line.

Include the full compileable project if you can. Gotta be something in there to explain it. Nothing wrong with the code presented as far as I can see.

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

this is core project,generated by cube ,and i changed a little,i conencted uart RX pin to vcc 3.3V,it also happen,whatever power on or reset

Pavel A.
Super User

With STM32H7 you most likely want to enable RTO (receive timeout) rather than the idle event.

Why the idle event can occur immediately? Because the receiver is idle. Use the RTO.