Skip to main content
Gabriel T
Senior
March 5, 2021
Solved

STM32H7 DMA2 wont trigger interrupt

  • March 5, 2021
  • 14 replies
  • 4152 views

Using STM32H743ZI

I am using SPI1 in 2 lines Rx only mode with DMA2 Stream 2 as in ST example

I use Rx DMA with a buffer located in D2 RAM. Using debugger I found that the first reception works well, data gets written into my buffer. But my DMA doesn't fire any interrupt, so the next transfers do not work.

Here is my init code :

hdma_spi1_rx.Instance = DMA2_Stream2;
 
hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_spi1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_spi1_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_spi1_rx.Init.PeriphBurst = DMA_PBURST_INC4;
hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
 
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
 Error_Handler();
}
 
__HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);
 
/* SPI1 interrupt Init */
__HAL_SPI_ENABLE_IT(hspi, SPI_IT_RXNE) ;
/* USER CODE BEGIN SPI1_MspInit 1 */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);

Any idea why my DMA2 peripheral wont trigger interrupt ?

This topic has been closed for replies.
Best answer by Gabriel T

My interrupts are working now, I added some flag clearing bare metal programming and removed breakpoints and it works now thanks !

14 replies

Tesla DeLorean
Guru
March 5, 2021

Do other interrupts work?

Using .cpp or C++ ?

The linker binds your IRQHandler?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Gabriel T
Gabriel TAuthor
Senior
March 5, 2021

I2C4 interrupts works. I am using .c, I am using GNU C

How can i check if my linker binds my IRQHandler ? in .map ?

waclawek.jan
Super User
March 5, 2021

> How can i check if my linker binds my IRQHandler ? in .map ?

The best way is to look at disasm and check if the ISR's address (e.g. as found in mapfile) is at the required position of the vector table (see startup file for the vector tables' source).

Some general hints to debug interrupts here.

JW

Gabriel T
Gabriel TAuthor
Senior
March 5, 2021

I checked DMA2 status register with debugger, after the first Rx. Both Half transfert complete flag and Transfert complete flag are 1.

It means my peripheral is working well. Do you have some link I can look to learn how to check the vector table ? I have never done it

Pavel A.
Super User
March 6, 2021

Is a function DMA2_Stream2_IRQHandler implemented somewhere? This is your handler.

This name must be exactly same as defined in your startup_stm32h743xx.s

--pa

Gabriel T
Gabriel TAuthor
Senior
March 5, 2021

Update I also checked NVIC ISER and NVIC->ISER[1]=0x400 0000 which means the bit 58 is 1, it is DMA2 Stream2 interrupt

waclawek.jan
Super User
March 6, 2021

How do you know the interrupt doesn't fire?

Are the HT and TC interrupts enabled locally, i.e. in respective DMA stream's control register?

You get the ISR address from mapfile or disasm view of that function in IDE, and then dump content of vector table e.g. in memory view of IDE.

Also, IMO, having an SPI interrupt together with DMA is nonsense, although it probably does not cause you the immediate problem.

JW

Gabriel T
Gabriel TAuthor
Senior
March 8, 2021

@Pavel A.​ 

In my startup_stm32h743xx.s, DMA2_Stream2_IRQHandler is registered here :

0693W000008wGPPQA2.pngAnd in "stm32h7xx_it.c" :

void DMA2_Stream2_IRQHandler(void)
{
 HAL_DMA_IRQHandler(&hdma_spi1_rx);
}

@Community member​ 

I know the interrupt doesnt fire because I put a breakpoint in DMA2_Stream2_IRQHandler()

Also, you think I shouldn't enable SPI1 interrupts ? Does the SPI throw an End of Tranfert interrupt when DMA is done or when it starts transfering ?

From looking at map file, DMA2_Stream2_IRQHandler address is 0x0000000008000fa0

With memory browser, I see a 08000FA1 value at 0x8000128 address.

0693W000008wGWLQA2.pngIt is the correct position and value (good news but bad news for diagnostic)

0693W000008wGotQAE.pngAlso I checked and SCB->VTOR = 0x8000000

waclawek.jan
Super User
March 8, 2021

Gabriel,

All you wrote above looks OK.

You've already checked that the HT and TC flags are set in the DMA status register, but are the HT and TC interrupts enabled locally, i.e. in respective DMA stream's control register?

The SPI interrupt: I don't use the 'H7 and I know its SPI is a very complicated beast, so there may be some merit in using it. I am not going to investigate this further, nor am I going to investigate what the Cube/HAL incantations you've used are supposed to do. In the older/simpler STM32, it's the DMA which is supposed to clear the SPI's RXNE status bit by reading the data.

JW

Gabriel T
Gabriel TAuthor
Senior
March 8, 2021

Yes, DMA2 Stream 2 configuration register gets set in HAL_SPI_Receive_DMA function

Here is register :

0693W000008wHMgQAM.png

waclawek.jan
Super User
March 8, 2021

Okay, so if

  • interrupts are locally enabled in DMA stream
  • interrupt flags in DMA are set
  • interrupt is enabled and pending in NVIC (you haven't reported about the "pending" part here)
  • ISR is in proper position of vector table and VTOR is checked
  • breakpoint inserted in the proper function (as checked in disasm view)
  • program won't stop on the breakpoint

then either breakpoints don't work (this can be circumvented by toggling a pin and observing in the ISR), or, which IMO may be more probable, processor runs with interrupts globally disabled or at a priority level which is higher than the ISR in questions' priority. I am lazy to look up how to check easily either of these, both involve looking at SCB registers.

JW