cancel
Showing results for 
Search instead for 
Did you mean: 

NVIC and invalid SCB->ICSR register with DMA2

jpeacock2399
Associate II
Posted on March 14, 2013 at 20:55

Environment is an STM32F205VF on a custom board, but the problem has also appeared on a STM3240G eval board with an STM32F407I.  Compiler is GCC 4.6.2 at optimize level O0 for debugging.

My application has extensive interrupt fault checking to detect a spurious interrupt request (IRQ) due to software or vector table errors.  I use the ICSR register to obtain the active IRQ when an interrupt service routine starts to verify the vector matches the interrupt request.  I have encountered a seemingly random event where the ICSR does not match the interrupt vector (for example, ICSR reports IRQ 44, CAN1 RX1, but the service routine vector is for DMA2 Stream 7, IRQ 93).  The vector table entries are correct.

I use DMA to transmit data out to USART1 on DMA2 stream 7, which is working.  The DMA service routine triggers on a TC at end of transmit.  The invalid ICSR IRQ occurs rarely, perhaps once an hour, which would imply some type of race conditon.  I'm at a loss to explain how the ICSR can report an active request for an interrupt which is not enabled.  I verified the NVIC settings: the CAN peripheral is not enabled and no NVIC interrupts for the CAN are enabled.  In any case the ICSR should not report an active CAN request after entering a DMA interrupt service routine.  I have two active DMA2 streams: USART1 TX uses stream 7, and ADC1 uses DMA2 stream 4.

I have not seen this behavior on the STM32F1xx series, so I suspect it may be related to the known problems with the DMA2 controller on STM32F2 and F4 parts, although this issue is not mentioned in the latest errata.  My theory is it may be related to tail-chaining, where the same service routine is triggered a second time while being serviced, but the ICSR is invalid on the second call.

Does anyone use the ICSR register in the SCB to check interrupt vectors?  Is the invalid ICSR an ARM problem or ST?

  Jack Peacock

#nvic-dma #nvic-dma2 #nvic-dma2 #nvic
8 REPLIES 8
jpeacock2399
Associate II
Posted on March 14, 2013 at 21:12

UPDATE:  I added some code to track IRQ history, since I intercept every interrupt vector.  Turns out it isn't related to tail-chaining, at least in calling the same IRQ vector twice in a row.  The spurious ICSR active IRQ does seem to vary, after another test it now shows vector 76, UART5, instead of vector 77, DMA2 stream 7.  UART5 is not enabled.  The IRQ history shows the same vector is not called twice in a row.

This may be a purely ICSR or DMA2 related problem, since the NVIC otherwise seems to be working correctly for numerous interrupts not related to DMA2.

  Jack Peacock
Posted on March 15, 2013 at 10:17

Random thoughts:

- does re-reading the register yield the same result?

- any pending interrupt at the same moment?

- it would be interesting to compare it to the content of (I)PSR register

JW

jpeacock2399
Associate II
Posted on March 17, 2013 at 00:15

MYSTERY DEEPENS:  The spurious interrupt vectors in ICSR disappear when all the DMA2 peripherals are using FIFO mode instead of direct mode.  For now I'm going to assume it's some side effect of the DMA2 bugs.

Amel NASRI
ST Employee
Posted on May 15, 2013 at 18:22

Hello Jack,

Could you please share a sample code? I try to reproduce the same issue.

Thanks!

ST.MCU

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

jpeacock2399
Associate II
Posted on May 16, 2013 at 15:55

Unfortunately the code which causes the problem runs about 20K lines, plus our legal dept. requires an NDA for all IP code releases.  The DMA2 peripherals involved are USART1 TX and RX, ADC1/2 ganged together, and ADC3.  All use FIFO mode in DMA. 

The problem appears primarily in the USART1 interrupt routine.  This is a reentrant routine for all USARTs, with the IRQ source determined by polling the ICSR at the start of the service routine.  All USART vectors point to the same service routine.  At random times the ICSR reports an active IRQ which is not enabled and often is not even a USART peripheral. 

The reentrant ADC interrupt service routine also uses ICSR to determine if the request is ADC1/2 or ADC3.  On occasion I trap a bad ICSR vector, so it is not limited to the USART.  As with the USART, using FIFO on all DMA2 channels seems to eliminate the problem.  I do not see the problem on DMA1.

  Jack Peacock

 I do not see spurious interrupt vectors from the NVIC (all unused vectors go to a trap routine).  The error seems to be solely in what the ICSR reports.
dthedens23
Associate II
Posted on May 16, 2013 at 22:51

this helped me out a bit

http://blog.frankvh.com/category/stm32/

there is errata about DMA 2 but it mentions peripherals other than the ones you are using and it talks about data corruption not spurious interrupts.

Posted on May 21, 2013 at 11:09

> The error seems to be solely in what the ICSR reports.

Did you consider some of the ideas I gave above, e.g. re-reading ICSR?

JW
jpeacock2399
Associate II
Posted on May 21, 2013 at 21:24

Reading the ICSR multiple times at the start of a service routine yields the same invalid number.  Since switching to DMA FIFO fixes the problem, and the vectors where I see the bad ICSR are ones linked to peripherals using DMA2 (USART1, ADC) I'd give it a 90% probability it's a hardware issue, especially since there are already known problems with DMA2.

  Jack Peacock