Sometimes finding the answer to these questions for an ARM device can be more difficult than simpler microcontrollers because the information is often spread across family and programming guides rather than included in the datasheet. In this case the answer appears to be on page 381 of the RM0090 Reference manual:
The STM32F4xx are able to handle external or internal events in order to wake up the core
(WFE). The wakeup event can be generated either by:
(I've removed normal external interrupt mode details)
or configuring an external or internal EXTI line in event mode. When the CPU resumes
from WFE, it is not necessary to clear the peripheral interrupt pending bit or the NVIC
IRQ channel pending bit as the pending bit corresponding to the event line is not set.
So it appears the main purpose is to enable wakeups without generating an interrupt or having to respond to interrupts during normal operation.
It's not mentioned in that guide and I'm not sure how applicable is to the STM32 architecture but on some other devices similar schemes can be useful to catch fast events without generating an interrupt. For example you may have an application where it's important to capture that a sub-microsecond event has occurred, but there's no need to respond to it quickly so you can just check a flag to see if it's occurred.
Edit: (5/2018) As of today, page number of referenced text is page 381 (formerly page 377)
Quick answer:
I would use the following (ugly) code:
if (NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] &
(uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F))
{
// It's enabled!
}
Explanation:
The NVIC_ISERx
registers are dual-purpose. If you write a 1
to a specific bit it will enable the interrupt. If you read a specific bit it will tell you if the interrupt is enabled:
You are using the SPL and so it is handling the mapping of interrupt sources to ISER registers and bit locations.
In the core_cm4.h
file, version 3.00, this is the NVIC_EnableIRQ()
function:
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */
NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */
}
It's interesting that they commented out the first line (which was identical to the same function in core_cm3.h
) and left it there; I'm guessing it was a bugfix and they forgot to remove the incorrect code. I got lost by all the typecasts, but I expect they are necessary.
My answer above is modeled after this NVIC_EnableIRQ()
function.
As far as system behavior, the following is taken from ST's PM0056 document (which is for M3, not M4, but the behavior is similar):
If a pending interrupt is enabled, the NVIC activates the interrupt based on its priority. If an interrupt is not enabled, asserting its interrupt signal changes the interrupt state to pending, but the NVIC never activates the interrupt, regardless of its priority.
If the "pending" flag gets set then the interrupt will be served as soon as you re-enable the interrupt.
Best Answer
STM32 DMA has some interrupts. You can try to use the DMA_IT_TC flag. I have not tested it with mode from array to periph, but it worked with periph to array (example from my code):
You should have also to set up NVIC interrupt (example):
TC flag means "transfer completed".
Example interrupt: