Skip to main content
Associate II
December 28, 2024
Question

HAL_NVIC_EnableIRQ does not end

    // DMA RX 설정
    __HAL_RCC_DMA1_CLK_ENABLE();  // DMA1 클럭 활성화

    hdma_rx.Instance = DMA_USART1;
    hdma_rx.Init.Request = DMA_REQUEST_USART1_RX;
    hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
   
    hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_rx.Init.Mode = DMA_CIRCULAR;  // 순환 모드
    hdma_rx.Init.Priority = DMA_PRIORITY_LOW;
   
    if (HAL_DMA_Init(&hdma_rx) != HAL_OK) { return IMU_INIT_FAILED; }
   
    __HAL_LINKDMA(&huart, hdmarx, hdma_rx);
    if (HAL_UART_Receive_DMA(&huart, &q_buf[0], DMA_BUFFER_IMU) != HAL_OK) {  return IMU_INIT_FAILED; }
    Delay_ms(1);

    __HAL_UART_CLEAR_FLAG(&huart, UART_FLAG_IDLE);

    HAL_NVIC_SetPriority(UART_IMU_IRQ, IT_PRIOR_IMU_PREM, IT_PRIOR_IMU_SUB);  // Set priority
    HAL_NVIC_EnableIRQ(UART_IMU_IRQ);          // Enable IRQ
    __HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE);
    __HAL_UART_CLEAR_FLAG(&huart, UART_FLAG_IDLE);
   
    return IMU_INIT_SUCCESS;
}
literally, HAL_NVIC_EnableIRQ does not end...
the parameters in code is as follows:
DMA_BUFFER_IMU : 128
UART_IMU_IRQ : USART1_IRQn
IT_PRIOR_IMU_PREM : 1
IT_PRIOR_IMU_SUB : 1
 
 
This topic has been closed for replies.

3 replies

gbm
Super User
December 28, 2024

HAL_UART_Receive_DMA is asynchronous and uses UART and DMA interrupts. Fiddling with interrupts manually while the HAL state machine is using them will usually lead to disaster. Don't play with UART until the RxComplete is called. Do not change interrupt priorities while the interrupt may be in use.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
yonggeonAuthor
Associate II
December 28, 2024

actually, this code is one of the part which initiate uart. such as..

 

void begin(){

    ~~
    ~~

   
    if (HAL_DMA_Init(&hdma_rx) != HAL_OK) { return IMU_INIT_FAILED; }
   
    __HAL_LINKDMA(&huart, hdmarx, hdma_rx);
    if (HAL_UART_Receive_DMA(&huart, &q_buf[0], DMA_BUFFER_IMU) != HAL_OK) {  return IMU_INIT_FAILED; }
    Delay_ms(1);

 

    __HAL_UART_CLEAR_FLAG(&huart, UART_FLAG_IDLE);

 

    HAL_NVIC_SetPriority(UART_IMU_IRQ, IT_PRIOR_IMU_PREM, IT_PRIOR_IMU_SUB);  // Set priority
    HAL_NVIC_EnableIRQ(UART_IMU_IRQ);          // Enable IRQ
    __HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE);
    __HAL_UART_CLEAR_FLAG(&huart, UART_FLAG_IDLE);
   
    return IMU_INIT_SUCCESS;

}

 

so i changed order of HAL_UART_Receive_DMA and NVIC & UART IT/flag lines then HAL_UART_Receive_DMA does not end at this time...

Tesla DeLorean
Guru
December 28, 2024

The MCU will tail-chain IRQ's continuously if the source of the interrupt is not cleared, or keeps asserting more rapidly that the handlers can clear them.

It will only return to foreground execution once everything is clear.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..