I don't know
Fork of mbed-src by
Diff: targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c
- Revision:
- 593:78ee8643776a
- Parent:
- 548:1abac31e188e
- Child:
- 627:4fa1328d9c60
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c Mon Jul 20 09:00:09 2015 +0100 @@ -46,7 +46,7 @@ #endif static uint32_t channel_ids[NUM_GPIO_CHANNELS] = { 0 }; // Relates pin number with interrupt action id -static uint32_t channel_ports[NUM_GPIO_CHANNELS] = { 0 }; +static uint8_t channel_ports[NUM_GPIO_CHANNELS/2] = { 0 }; // Storing 2 ports in each uint8 static gpio_irq_handler irq_handler; static void GPIOINT_IRQDispatcher(uint32_t iflags); @@ -57,7 +57,9 @@ return; } - uint32_t isRise = GPIO_PinInGet(channel_ports[pin], pin); + //we are storing two ports in each uint8, so we must aquire the one we want. + // If pin is odd, the port is encoded in the 4 most significant bits. If pin is even, the port is encoded in the 4 least significant bits + uint8_t isRise = GPIO_PinInGet((pin & 0x1) ? channel_ports[(pin>>1) & 0x7] >> 4 & 0xF : channel_ports[(pin>>1) & 0x7] & 0xF, pin); // Get trigger event gpio_irq_event event = IRQ_NONE; @@ -77,40 +79,39 @@ /* Pin and port index encoded in one uint32. * The four least significant bits represent the pin number * The remaining bits represent the port number */ - obj->pin = pin & 0xF; - obj->port = pin >> 4; + obj->pin = pin; obj->risingEdge = 0; obj->fallingEdge = 0; } int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - /* Init pins */ + // Init pins gpio_irq_preinit(obj, pin); - /* Initialize GPIO interrupt dispatcher */ + // Initialize GPIO interrupt dispatcher NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn); NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); NVIC_EnableIRQ(GPIO_EVEN_IRQn); /* Relate pin to interrupt action id */ - channel_ids[obj->pin] = id; - /* Relate the pin number to a port */ - channel_ports[obj->pin] = obj->port; + channel_ids[obj->pin & 0xF] = id; + + // Relate the pin number to a port. If pin in is odd store in the 4 most significant bits, if pin is even store in the 4 least significant bits + channel_ports[(obj->pin >> 1) & 0x7] = (obj->pin & 0x1) ? (channel_ports[(obj->pin >> 1) & 0x7] & 0x0F) | (obj->pin & 0xF0) : (channel_ports[(obj->pin >> 1) & 0x7] & 0xF0) | ((obj->pin >> 4) & 0xF); /* Save pointer to handler */ irq_handler = handler; - pin_mode(obj->pin | (obj->port << 4), Input); - + pin_mode(obj->pin, Input); return 0; } void gpio_irq_free(gpio_irq_t *obj) { // Destructor - channel_ids[obj->pin] = 0; + channel_ids[obj->pin & 0xF] = 0; gpio_irq_disable(obj); // Disable interrupt channel - pin_mode(obj->pin | (obj->port << 4), Disabled); // Disable input pin + pin_mode(obj->pin, Disabled); // Disable input pin } void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) @@ -132,7 +133,7 @@ bool was_disabled = false; if(GPIO->IEN == 0) was_disabled = true; - GPIO_IntConfig(obj->port, obj->pin, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge); + GPIO_IntConfig((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin &0xF, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge); if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) { blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); } @@ -141,12 +142,12 @@ inline void gpio_irq_enable(gpio_irq_t *obj) { if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); - GPIO_IntEnable(1 << obj->pin); // pin mask for pins to enable + GPIO_IntEnable(1 << obj->pin & 0xF); // pin mask for pins to enable } inline void gpio_irq_disable(gpio_irq_t *obj) { - GPIO_IntDisable(1 << obj->pin); // pin mask for pins to disable + GPIO_IntDisable(1 << obj->pin & 0xF); // pin mask for pins to disable if(GPIO->IEN == 0) unblockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); } @@ -171,7 +172,7 @@ while(iflags) { irqIdx = GPIOINT_MASK2IDX(iflags); - /* clear flag*/ + /* clear flag */ iflags &= ~(1 << irqIdx); /* call user callback */ @@ -188,13 +189,12 @@ void GPIO_EVEN_IRQHandler(void) { uint32_t iflags; - - /* Get all even interrupts. */ + /* Get all even interrupts */ iflags = GPIO_IntGetEnabled() & 0x00005555; - /* Clean only even interrupts. */ + /* Clean only even interrupts*/ + GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); } @@ -209,12 +209,11 @@ { uint32_t iflags; - /* Get all odd interrupts. */ + /* Get all odd interrupts */ iflags = GPIO_IntGetEnabled() & 0x0000AAAA; - /* Clean only even interrupts. */ + /* Clean only even interrupts */ GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); }