Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Mon Jul 20 09:00:09 2015 +0100
Parent:
592:a274ee790e56
Child:
594:5afbce4ea2da
Commit message:
Synchronized with git revision a68b724d07788e6389ea4d52c622aad767953758

Full URL: https://github.com/mbedmicro/mbed/commit/a68b724d07788e6389ea4d52c622aad767953758/

[Silicon Labs] Bring EFM32 HAL up to date

Changed in this revision

targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_MICRO/startup_efm32gg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_STD/startup_efm32gg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/efm32hg.sct Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/startup_efm32hg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_GCC_ARM/efm32hg.ld Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/cmsis_nvic.h Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_MICRO/startup_efm32lg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/startup_efm32lg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_MICRO/startup_efm32wg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_STD/startup_efm32wg.S Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.S Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_MICRO/startup_efm32gg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_MICRO/startup_efm32gg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20020000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_STD/startup_efm32gg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_STD/startup_efm32gg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20020000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/efm32hg.sct	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/efm32hg.sct	Mon Jul 20 09:00:09 2015 +0100
@@ -8,7 +8,7 @@
    *(InRoot$$Sections)
    .ANY (+RO)
   }
-  RW_IRAM1 0x20000080 0x00001F80  {  ; RW data
+  RW_IRAM1 0x20000098 0x00001F68  {  ; RW data
    .ANY (+RW +ZI)
   }
 }
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/startup_efm32hg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/startup_efm32hg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20002000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_GCC_ARM/efm32hg.ld	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_GCC_ARM/efm32hg.ld	Mon Jul 20 09:00:09 2015 +0100
@@ -16,8 +16,8 @@
 
 /* MBED: mbed needs to be able to dynamically set the interrupt vector table.
  * We make room for the table at the very beginning of RAM, i.e. at
- * 0x20000000. We need (16+20) * sizeof(uint32_t) = 144 bytes for EFM32HG */
-__vector_size = 0x90;
+ * 0x20000000. We need (16+21) * sizeof(uint32_t) = 144 bytes for EFM32HG */
+__vector_size = 0x94;
 
 /* Linker script to place sections and symbol values. Should be used together
  * with other linker script that defines memory regions FLASH and RAM.
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/cmsis_nvic.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/cmsis_nvic.h	Mon Jul 20 09:00:09 2015 +0100
@@ -9,7 +9,7 @@
 
 #include "cmsis.h"
 
-#define NVIC_NUM_VECTORS      (16 + 16)   // CORE + MCU Peripherals
+#define NVIC_NUM_VECTORS      (16 + 21)   // CORE + MCU Peripherals
 #define NVIC_USER_IRQ_OFFSET  16
 
 #ifdef __cplusplus
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_MICRO/startup_efm32lg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_MICRO/startup_efm32lg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20008000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/startup_efm32lg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/startup_efm32lg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20008000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_MICRO/startup_efm32wg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_MICRO/startup_efm32wg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20008000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_STD/startup_efm32wg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_STD/startup_efm32wg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20008000
 
 
 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.S	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.S	Mon Jul 20 09:00:09 2015 +0100
@@ -33,7 +33,7 @@
 
                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
 Stack_Mem       SPACE   Stack_Size
-__initial_sp
+__initial_sp    EQU     0x20001000
 
 
 ; <h> Heap Configuration
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h	Mon Jul 20 09:00:09 2015 +0100
@@ -103,7 +103,7 @@
     PullDown = InputPullDown,
     OpenDrain = WiredAnd,
     PullNone = PushPull,
-    PullDefault = PullUp
+    PullDefault = PushPull
 } PinMode;
 
 #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h	Mon Jul 20 09:00:09 2015 +0100
@@ -102,7 +102,7 @@
     PullDown = InputPullDown,
     OpenDrain = WiredAnd,
     PullNone = PushPull,
-    PullDefault = PullUp
+    PullDefault = PushPull
 } PinMode;
 
 #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h	Mon Jul 20 09:00:09 2015 +0100
@@ -102,7 +102,7 @@
     PullDown = InputPullDown,
     OpenDrain = WiredAnd,
     PullNone = PushPull,
-    PullDefault = PullUp
+    PullDefault = PushPull
 } PinMode;
 
 #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h	Mon Jul 20 09:00:09 2015 +0100
@@ -102,7 +102,7 @@
     PullDown = InputPullDown,
     OpenDrain = WiredAnd,
     PullNone = PushPull,
-    PullDefault = PullUp
+    PullDefault = PushPull
 } PinMode;
 
 #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h	Mon Jul 20 09:00:09 2015 +0100
@@ -102,7 +102,7 @@
     PullDown = InputPullDown,
     OpenDrain = WiredAnd,
     PullNone = PushPull,
-    PullDefault = PullUp
+    PullDefault = PushPull
 } PinMode;
 
 #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c	Mon Jul 20 09:00:09 2015 +0100
@@ -19,9 +19,28 @@
 #include "mbed_assert.h"
 #include "sleepmodes.h"
 
-uint8_t gpio_get_index(gpio_t *obj)
+
+void gpio_write(gpio_t *obj, int value)
 {
-    return 0;
+    if (value) {
+        GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin
+    } else {
+        GPIO_PinOutClear((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF);
+    }
+}
+
+int gpio_read(gpio_t *obj)
+{
+    if (obj->dir == PIN_INPUT) {
+        return GPIO_PinInGet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin
+    } else {
+        return GPIO_PinOutGet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF);
+    }
+}
+
+int gpio_is_connected(const gpio_t *obj)
+{
+    return (obj->pin | 0xFFFFFF00 )!= (PinName)NC;
 }
 
 /*
@@ -44,25 +63,49 @@
     obj->pin = pin;
 }
 
-void gpio_pin_enable(gpio_t *obj, uint8_t enable)
-{
-    if (enable) {
-        pin_mode(obj->pin, obj->mode);
-    } else {
-        pin_mode(obj->pin, Disabled); // TODO_LP return mode to default value
-    }
-}
-
 void gpio_mode(gpio_t *obj, PinMode mode)
 {
+        if(obj->dir == PIN_INPUT) {
+        switch(mode) {
+            case PullDefault:
+                mode = Input;
+                break;
+            case PullUp:
+                mode = InputPullUp;
+                break;
+            case PullDown:
+                mode = InputPullDown;
+                break;
+            default:
+                break;
+        }
+        
+        //Handle DOUT setting
+        if((mode & 0x10) != 0) {
+            //Set DOUT
+            GPIO->P[(obj->pin >> 4) & 0xF].DOUTSET = 1 << (obj->pin & 0xF);
+        } else {
+            //Clear DOUT
+            GPIO->P[(obj->pin >> 4) & 0xF].DOUTCLR = 1 << (obj->pin & 0xF);
+        }
+    } else {
+        switch(mode) {
+            case PullDefault:
+                mode = PushPull;
+                break;
+            case PullUp:
+                mode = WiredAndPullUp;
+                break;
+            case PullDown:
+                mode = WiredOrPullDown;
+                break;
+            default:
+                break;
+        }
+    }
+    
     obj->mode = mode; // Update object
     pin_mode(obj->pin, mode); // Update register
-
-    //Handle pullup for input
-    if(mode == InputPullUp) {
-        //Set DOUT
-        GPIO->P[(obj->pin >> 4) & 0xF].DOUTSET = 1 << (obj->pin & 0xF);
-    }
 }
 
 // Used by DigitalInOut to set correct mode when direction is set
@@ -78,4 +121,3 @@
             break;
     }
 }
-
--- 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);
 }
 
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h	Fri Jul 17 09:15:10 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef MBED_GPIO_OBJECT_H
-#define MBED_GPIO_OBJECT_H
-
-#include "em_gpio.h"
-#include "PinNames.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
-    PinName pin;
-    PinMode mode;
-    PinDirection dir;
-} gpio_t;
-
-static inline void gpio_write(gpio_t *obj, int value)
-{
-    if (value) {
-        GPIO_PinOutSet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin
-    } else {
-        GPIO_PinOutClear((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF);
-    }
-}
-
-static inline int gpio_read(gpio_t *obj)
-{
-    if (obj->dir == PIN_INPUT) {
-        return GPIO_PinInGet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin
-    } else {
-        return GPIO_PinOutGet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF);
-    }
-}
-
-static inline int gpio_is_connected(const gpio_t *obj)
-{
-    return obj->pin != (PinName)NC;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h	Mon Jul 20 09:00:09 2015 +0100
@@ -28,6 +28,12 @@
 extern "C" {
 #endif
 
+typedef struct {
+    PinName pin:8;
+    PinMode mode:6;
+    PinDirection dir:2;
+} gpio_t;
+
 #if DEVICE_ANALOGIN
 struct analogin_s {
     ADC_TypeDef *adc;
@@ -79,10 +85,9 @@
 
 #if DEVICE_INTERRUPTIN
 struct gpio_irq_s {
-    uint32_t port;
-    PinName pin;
-    uint32_t risingEdge;
-    uint32_t fallingEdge;
+    PinName pin:8; // Pin number 4 least significant bits, port number 4 most significant bits
+    uint32_t risingEdge:1;
+    uint32_t fallingEdge:1;
 };
 #endif
 
@@ -137,7 +142,6 @@
 } sleepstate_enum;
 #endif
 
-#include "gpio_object.h"
 
 #ifdef __cplusplus
 }
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c	Fri Jul 17 09:15:10 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c	Mon Jul 20 09:00:09 2015 +0100
@@ -977,7 +977,7 @@
         /* If there is still data in the TX buffer, setup a new transfer. */
         if (obj->tx_buff.pos < obj->tx_buff.length) {
             /* Find position and remaining length without modifying tx_buff. */
-            void* tx_pointer = obj->tx_buff.buffer + obj->tx_buff.pos;
+            void* tx_pointer = (char*)obj->tx_buff.buffer + obj->tx_buff.pos;
             uint32_t tx_length = obj->tx_buff.length - obj->tx_buff.pos;
 
             /* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */