I don't know

Dependents:   MX106-finaltest

Fork of mbed-src by mbed official

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