In my project, I use a central event source to inform the whole system about GPIO events. In order to distinguish individual sources (i.e. pins) that triggered the event, I so far only encode the GPIO pad in the propagated eventflags_t value like this:
Code: Select all
static void isrCallback(void* args) {
chSysLockFromISR();
// args is known to point to an ioline_t value
chEvtBroadcastFlagsI(&gpioEvtSource, (eventflags_t)1 << PAL_PAD(*((ioline_t*)args)));
chSysUnlockFromISR();
}
However, a major drawback of this solution is that I can only use a single port per pad, thus limiting the number of distinguishable GPIO events to 16 on STM32 MCUs.
So what came to my mind is to encode the port as well. Since there is no MCU that features more than 24 EXTI lines (I think), there would be 8 bits left in the eventflags_t value to encode a port. Using the PAL_PORT() macro in a similar manner is not feasible, though, as it returns a pointer to the according GPIO port memory address.
What I am rather looking for is an integer representation of ports, like
Code: Select all
uint8_t porta = ENCODE_PORT(GPIOA); // 0
uint8_t portb = ENCODE_PORT(GPIOB); // 1
uint8_t portc = ENCODE_PORT(GPIOC); // 2
...
Code: Select all
static void isrCallback(void* args) {
chSysLockFromISR();
// args is known to point to an ioline_t value
chEvtBroadcastFlagsI(&gpioEvtSource, ((eventflags_t)1 << PAL_PAD( *((ioline_t*)args)) ) |
((eventflags_t)1 << (ENCODE_PORT(PAL_PORT(*((ioline_t*)args))) + 24)));
chSysUnlockFromISR();
}
Is there something like that already in place? If not, can it be introdoced at all, since this whole encoding is quite platform dependent?