2014-06-13 11:42 AM
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.cMy 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-conflict2014-06-14 06:42 AM
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.2014-06-16 05:42 AM
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);2014-06-16 07:58 AM
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.2014-06-16 08:07 AM
> 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). JW2014-06-16 10:27 AM
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 requirementto 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, Forrest2014-07-09 09:32 AM
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...