modm API documentation
External Interrupt/Event Controller (EXTI)

Classes

class  modm::platform::Exti
 

Macros

#define MODM_EXTI_HANDLER_STORAGE   sizeof(void*)
 

Detailed Description

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);

Module Options

modm:platform:exti: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>();
Warning
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>

Generated with: yes in [yes, no]