aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2020-03-13 15:28:40 +0100
committerHarald Welte <laforge@osmocom.org>2020-03-13 15:28:40 +0100
commite42492971e130b4c03229f6b818a9b1183f1ff36 (patch)
tree41436efad1834044953e96489c74dc0b50ae90ef
parenta625ef0d9b81cc90b31308a0c9c549909515c6c8 (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.c26
-rw-r--r--hardware/board_gpio.gnumericbin154648 -> 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
index 1ec9ff6..0e4893d 100644
--- a/hardware/board_gpio.gnumeric
+++ b/hardware/board_gpio.gnumeric
Binary files differ