External Interrupt/Event Controller (EXTI)¶
lbuild module: modm:platform:exti
This driver provides an API for configuring all EXTI lines via register access. Note that you need to pass a mask, which allows you to configure multiple EXTI lines at once.
A typical use-case is to trigger on multiple GPIO inputs:
// all trigger on both edges
Exti::setTriggers<GpioA0, GpioC4, GpioD6>(Exti::Trigger::BothEdges);
// Sets the specific GPIO port per line
Exti::setTriggerSources<GpioA0, GpioC4, GpioD6>();
// Enables EXTI4 and EXTI9_5 IRQ handlers with the same priority of 10!
Exti::enableVectors<GpioC4, GpioD6>(10);
// Sets a different priority for EXTI0
Exti::enableVector<GpioA0>(5);
// Enable all interrupts at the same time
Exti::enableInterrupts<GpioA0, GpioC4, GpioD6>();
// You must manually define the IRQ handlers but *only*
// if you disable the `with_handlers` option!
MODM_ISR(EXTI0) { Exti::acknowledgeFlags<GpioA0>(); }
MODM_ISR(EXTI4) { Exti::acknowledgeFlags<GpioC4>(); }
MODM_ISR(EXTI9_5) { Exti::acknowledgeFlags<GpioD6>(); }
Note that you can also use this to configure more than just GPIO trigger sources, you can configure all other device specific EXTI lines as well. However, you need to manually configure the NVIC vector and possibly also configure the sending peripheral separately.
// Configure the RTC peripheral to send the tamper event
// Line 21 is the RTC tamper alert on STM32F4x6
Exti::setTrigger(1ul << 21, Exti::Trigger::RisingEdge);
Exti::enableInterrupts(1ul << 21);
// Manually enable the RTC_Alarm IRQ
NVIC_SetPriority(RTC_Alarm_IRQn, 10);
NVIC_EnableIRQ(RTC_Alarm_IRQn);
// Different IRQ naming scheme, not EXTI_RTC!
MODM_ISR(RTC_Alarm) {}
You can also trigger events instead of interrupts to facilitate WFE.
Exti::setTrigger(1ul << 21, Exti::Trigger::FallingEdge);
Exti::enableEvents(1ul << 21);
This module is only available for stm32.
Options¶
with_handlers¶
Use callbacks for GPIO lines
To simplify the external IRQ management of external GPIO triggers, you can use
the connect method to attach a void(uint8_t)
callback to EXTI lines 0-15,
which gets passed the triggered line number as an argument:
Exti::connect<GpioA0>(Exti::Trigger::FallingEdge,
[count=uint32_t(0)](uint8_t line) mutable
{
MODM_LOG_INFO << "Line " << line << " triggered " << ++count << " times!" << modm::endl;
});
// to disable the handler and IRQ later
Exti::disconnect<GpioA0>();
Duplicate Symbols for EXTI_IRQHandler
This option internally defines all MODM_ISR(EXTI*)
IRQs, so you cannot
define them anymore in your application!
The callback is implemented using modm::inplace_function
, therefore uses no
heap, but has a fixed storage size of sizeof(void*)
by default.
You can increase this storage size by defining a new global storage size
MODM_EXTI_HANDLER_STORAGE=bytes
in your project.xml
:
<library>
<collectors>
<collect name="modm:build:cppdefines">MODM_EXTI_HANDLER_STORAGE=12</collect>
</collectors>
</library>
Default: yes
Inputs: [yes, no]
Dependencies¶
Limited availability: Check with 'lbuild discover' if this module is available for your target!