diff options
author | Harald Welte <laforge@osmocom.org> | 2020-03-13 15:28:40 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-03-13 15:28:40 +0100 |
commit | e42492971e130b4c03229f6b818a9b1183f1ff36 (patch) | |
tree | 41436efad1834044953e96489c74dc0b50ae90ef | |
parent | a625ef0d9b81cc90b31308a0c9c549909515c6c8 (diff) |
pio_it.c: Permit repeated calls to PIO_ConfigureIt()
The original code assumes that calls to PIO_ConfigureIt() are only
made once e.g. during board start-up. Hoewever, we call those
at USB SetConfiguration time, when we know which particular hardware
function we are supposed to perform. This means that after the host
has issued SetConfiguration more than a given number of times, the
code will assert() due to overflow of the static array.
Let's check if we already have allocated an array slot for a given pin
and reuse that allocated array bucket rather than allocating new ones
for the same pin.
Change-Id: I0c46d4b51eeebd58a8786d65e31e7a84e65b6a8e
Related: OS#4454
-rw-r--r-- | firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c | 26 | ||||
-rw-r--r-- | hardware/board_gpio.gnumeric | bin | 154648 -> 8713 bytes |
2 files changed, 19 insertions, 7 deletions
diff --git a/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c b/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c index 7feccd1..781b914 100644 --- a/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c +++ b/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c @@ -211,6 +211,16 @@ extern void PIO_InitializeInterrupts( uint32_t dwPriority ) NVIC_EnableIRQ( PIOC_IRQn ) ; } +static InterruptSource *find_intsource4pin(const Pin *pPin) +{ + unsigned int i ; + for (i = 0; i < _dwNumSources; i++) { + if (_aIntSources[i].pPin == pPin) + return &_aIntSources[i]; + } + return NULL; +} + /** * Configures a PIO or a group of PIO to generate an interrupt on status * change. The provided interrupt handler will be called with the triggering @@ -228,15 +238,17 @@ extern void PIO_ConfigureIt( const Pin *pPin, void (*handler)( const Pin* ) ) assert( pPin ) ; pio = pPin->pio ; - assert( _dwNumSources < MAX_INTERRUPT_SOURCES ) ; - - /* Define new source */ - TRACE_DEBUG( "PIO_ConfigureIt: Defining new source #%" PRIu32 ".\n\r", _dwNumSources ) ; - pSource = &(_aIntSources[_dwNumSources]) ; - pSource->pPin = pPin ; + pSource = find_intsource4pin(pPin); + if (!pSource) { + /* Define new source */ + TRACE_DEBUG( "PIO_ConfigureIt: Defining new source #%" PRIu32 ".\n\r", _dwNumSources ) ; + assert( _dwNumSources < MAX_INTERRUPT_SOURCES ) ; + pSource = &(_aIntSources[_dwNumSources]) ; + pSource->pPin = pPin ; + _dwNumSources++ ; + } pSource->handler = handler ; - _dwNumSources++ ; /* PIO3 with additional interrupt support * Configure additional interrupt mode registers */ diff --git a/hardware/board_gpio.gnumeric b/hardware/board_gpio.gnumeric Binary files differindex 1ec9ff6..0e4893d 100644 --- a/hardware/board_gpio.gnumeric +++ b/hardware/board_gpio.gnumeric |