cancel
Showing results for 
Search instead for 
Did you mean: 

DMA interrupts don't work

Vlad2022
Associate II

Microcontroller STM32F401. The DMA controller transfers data from memory to the DR register of the SPI interface. With the HTIE and TCIE bits set, DMA is not included in the interrupt handler. At the end of the data array transfer, the program freezes, there is no interruption in half of the packet, and DMA is not included in the void DMA2_Stream5_IRQHandler(void) function.

Initializing DMA:

void DMA2_Init(void) {
 
   RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; 
 
   DMA2_Stream5->M0AR |= (uint32_t)(&data);
   DMA2_Stream5->PAR |= (uint32_t)(&SPI1->DR); 
   DMA2_Stream5->NDTR = 57600;
 
   DMA2_Stream5->CR |= DMA_SxCR_MSIZE_0;
   DMA2_Stream5->CR |= DMA_SxCR_PSIZE_0; 
 
   DMA2_Stream5->CR |= DMA_SxCR_CHSEL_1 |
   DMA_SxCR_CHSEL_0;
   DMA2_Stream5->CR |= DMA_SxCR_DIR_0;
 
   DMA2_Stream5->CR |= DMA_SxCR_TCIE;
   DMA2_Stream5->CR |= DMA_SxCR_HTIE;
   NVIC_EnableIRQ(DMA2_Stream5_IRQn);
 
   DMA2_Stream5->CR |= DMA_SxCR_EN;
}

Interrupt Handler:

void DMA2_Stream5_IRQHandler(void) {
...
}

18 REPLIES 18

The program enters the interrupt and works endlessly in it, the working code stops executing. At the same time, neither the DMA2_Stream5 interrupt handler is started, nor the program does not get into HardFault or other errors.

My programmer does not support debugging.

> nothing happens on half of the transmission,

How do you know?

JW

TDK
Guru

> But after enabling interrupts, the program stops running.

Possibly (probably) the MCU is jumping to the IRQ handler and either because you're failing to clear flags, or because it's being triggered too often, the MCU fails to make progress in the main loop.

Posting the complete IRQ handler code would help.

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

I assume that when the HTIE bit is enabled, the program should enter the interrupt and, if not reset the flag, stay in it. Through DMA over SPI, I paint over the display with color. If you put the interrupt handler empty, then the program on half of the display should enter an infinite interrupt. I have a full filling of the display and only then enters the interrupt.

void DMA2_Stream5_IRQHandler(void) {
	GPIOC->BSRR |= GPIO_BSRR_BR_13;
 
	DMA2->HIFCR |= DMA_HIFCR_CTCIF5;
	DMA2->HIFCR |= DMA_HIFCR_CHTIF5;
}

At the very beginning of the interrupt, I give the command to turn on the standard LED. However, my LED does not light up when interrupts are turned on.

> I assume that when the HTIE bit is enabled, the program should enter the interrupt and, if not reset the

> flag, stay in it. Through DMA over SPI, I paint over the display with color. If you put the interrupt handler

> empty, then the program on half of the display should enter an infinite interrupt. I have a full filling of the

> display and only then enters the interrupt.

DMA continues to work regardless of whether you are in interrupt or not. So, the half-transfer interrupt fires, processor gets stuck in the interrupt, but DMA continues to fill SPI thus draw on your display.

JW

  1. You are resetting the pin with BR bit, not setting with BS bit.
  2. None of those lines need a read-modify-write operation.
  3. Both interrupt flags can be cleared with a single operation.
void DMA2_Stream5_IRQHandler(void) {
	GPIOC->BSRR = GPIO_BSRR_BS_13;
 
	DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
}

Thank you, so my assumption is wrong and the HTIE interrupt works.

On my board, the LED is connected to VCC and to turn it on, you need to set 0 on the controller pin. I'll try to run your corrected code.