cancel
Showing results for 
Search instead for 
Did you mean: 

DMA2 ISR and TIMER ISR conflict

forrest
Associate II
Posted on June 13, 2014 at 20:42

Hello,

I am confused by a DMA2 ISR and TIMER ISR conflict which is occurring in my project.

The project is based upon the FATFS SDIO example project provided with the STM32F4Discovery PCB.

I have had no trouble whatsoever implementing FATFS SDIO SD card writes.

However, when I attempt even 1 single sector write (512 Bytes) from within a TIMER ISR,

the code grinds to a halt waiting for a DMA transfer to complete. This happens in function:

SD_Error SD_WaitWriteOperation(void)

{

  SD_Error errorstatus = SD_OK;

  uint32_t timeout;

  timeout = SD_DATATIMEOUT;

  while ((DMAEndOfTransfer == 0x00) && (TransferEnd == 0) && (TransferError == SD_OK) && (timeout > 0))

  {

    timeout--;

  }

...

found in stm32f4_discovery_sdio_sd.c

My TIMER13 ISR is firing every 5ms and it works perfectly until I attempt to write to the SD card. If I wait long enough (5-6 minutes per sector write attempt) the last sector attempt completes and the TIMER13 ISR returns to firing every 5ms.

This is very odd behavior. Both the SDIO SD card write and the TIMER13 5ms ISR operate perfectly apart from each other. Combining them causes both operations to fail.

Here is why none of this makes sense to me:

1) TIMER13 is not capable of generating a DMA request.

2) TIMER13 is on a different peripheral clock than the DMA2 channel 3 used for the SDIO interface.

3) I disable the TIMER13 ISR before calling the SD card sector write THEN enable it after the sector write is completed. My timing test show that a sector write takes about 3 ms.

How is it possible that these could collide?

Before I post a boat load of code here in the forum, Is there any general guidance that can be provided to get me over the initial hump here?

I would greatly appreciate hearing your thoughts.

Thank You,  

Forrest

#dma2-isr-and-timer-isr-conflict
6 REPLIES 6
zzdz2
Associate II
Posted on June 14, 2014 at 15:42

Do you have the same priority level for both irqs? I think it would explain the deadlock.

You can try a lower priority level for TIM irq.

forrest
Associate II
Posted on June 16, 2014 at 14:42

Hi knik,

Good question. I do use a lower priority for the TIMER13 interrupt.

Changing the DMA2 stream from 3 to 6 caused the TIMER13 interrupt to continue without issue.

However, now the SD card interface does not work at all.

The FATFS functions return ''FR_INVALID_OBJECT''

Is this a known bug?

I read the errata sheet for the STM32F407 and did not see anything that pertained to this.

Thanks,

Forrest

 // Setup the global interrupt for TIMER13:

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  // Experimenting here in an attempt to get the SDIO DMA WAIT error/hangup to 

  // go away. Dropping the priority levels as done below has NO EFFECT.

  //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

  //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  // Initialize the DMA2_Stream3/6_IRQn 

  // DMA2 STREAM3/6 Interrupt ENABLE

  NVIC_InitTypeDef NVIC_InitStructure;

  //NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn;

  // The priority here does nor seem to matter: tried 0, 1,2 and 3

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  // The next two lines are not included in the example. Should they be??

  // They make no difference when DMA2_Stream6 is used.

 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 NVIC_Init(&NVIC_InitStructure);

Posted on June 16, 2014 at 16:58

Is this a known bug? I read the errata sheet for the STM32F407 and did not see anything that pertained to this.

Yes, bugs in coding usually don't get into the errata. The SDIO examples aren't particularly robust, or of commercial grade, calling them under interrupt is also probably not the wisest choice. Writing is particularly problematic as the DMA completes long before the FIFO flushes. The NVIC would also need to be programmed with the right priority grouping so the SDIO interrupt would preempt the TIM interrupt.

How the 4-bit priority is handled by the NVIC should be covered by the core (ARM) documentation, and Joseph Yiu's books.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on June 16, 2014 at 17:07

> How the 4-bit priority is handled by the NVIC should be covered by the core (ARM) documentation,

... as duplicated in ST's PM0056 and PM0214 (in both ch 2.3.5 and 2.3.6 and description of SCB_AIRCR).

JW

forrest
Associate II
Posted on June 16, 2014 at 19:27

HI Clive1,

Thanks for your response.

I now realize that I was not as clear as I could have been with my statement about a known bug.

Is there a known hardware bug regarding the use of a DMA channel in conjunction with a timer ISR?

I have read the ST application note(AN4013) on using the DMA controller and I have read the errata sheet for the STM32F407. There was no reference to a known DMA/ISR bug in those docs.

The priorities of my SDIO interface, Timer13 ISR and DMA2 stream 3 are as follows:

SDIO is priority 0:

  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

Timer13 ISR is priority 2 :

  NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

DMA2 stream3 is priority 1:

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

The Timer13 ISR is disabled before calling the SDIO write function and Timer13 ISR is re-enabled after the SDIO operation completes.

I am calling the SDIO write function from the Timer13 ISR because of a system timing requirement

to write data at a specific interval. I am not at liberty to relax that requirement.

I am new to ARM development and I wonder if I am missing something fundamental here.

ISRs are simple. I have written them for years.

Any additional thoughts?

Thanks, 

Forrest

  

forrest
Associate II
Posted on July 09, 2014 at 18:32

Thought I'd take a moment to let the forum readers know how this turned out.

The issue was actually caused by the nature of the f_write() function which is a blocking function and cannot be used within an ISR context. Moving the f_write() function call outside of the ISR context resolved the problem.

I had actually ported the design to work on an RTOS (ChibiOS) and the same DMA lock up ocurred there. Giovanni, the author of the RTOS informed me that the f_write() function could not be used within an ISR context.

This causes some complications in rewriting the code to work around the issue but it is possible to move on now that the issue is understood.

Hope That helps some folks...