diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h index 6643048906..f66537153d 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h @@ -103,7 +103,7 @@ typedef enum { PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h index 815340b129..ac2d73382f 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h @@ -102,7 +102,7 @@ typedef enum { PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h index ca2004dab5..984a5b3690 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h @@ -102,7 +102,7 @@ typedef enum { PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h index ca2004dab5..984a5b3690 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h @@ -102,7 +102,7 @@ typedef enum { PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h index df85387eeb..521c422f82 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h @@ -102,7 +102,7 @@ typedef enum { PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c index f1c0566094..55a0a374c4 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c @@ -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 @@ void gpio_init(gpio_t *obj, PinName pin) 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 @@ void gpio_dir(gpio_t *obj, PinDirection direction) break; } } - diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c index 3e2ae5919f..c2f48d35fe 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c @@ -46,7 +46,7 @@ __STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask) #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 @@ static void handle_interrupt_in(uint8_t pin) 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 @@ void gpio_irq_preinit(gpio_irq_t *obj, PinName pin) /* 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 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) 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 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) 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); } @@ -187,14 +188,13 @@ static void GPIOINT_IRQDispatcher(uint32_t iflags) ******************************************************************************/ void GPIO_EVEN_IRQHandler(void) { - uint32_t iflags; + uint32_t iflags; + /* Get all even interrupts */ + iflags = GPIO_IntGetEnabled() & 0x00005555; - /* Get all even interrupts. */ - iflags = GPIO_IntGetEnabled() & 0x00005555; + /* Clean only even interrupts.*/ - /* Clean only even interrupts. */ GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); } @@ -207,14 +207,13 @@ void GPIO_EVEN_IRQHandler(void) ******************************************************************************/ void GPIO_ODD_IRQHandler(void) { - uint32_t iflags; + uint32_t iflags; - /* Get all odd interrupts. */ - iflags = GPIO_IntGetEnabled() & 0x0000AAAA; + /* Get all odd interrupts by */ + iflags = GPIO_IntGetEnabled() & 0x0000AAAA; - /* Clean only even interrupts. */ + /* Clean only even interrupts.*/ GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); } diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h deleted file mode 100644 index 9e2569728c..0000000000 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h +++ /dev/null @@ -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 diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h index 986bc761e2..1dd923e06e 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h @@ -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 @@ struct pwmout_s { #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 @@ typedef enum { } sleepstate_enum; #endif -#include "gpio_object.h" #ifdef __cplusplus }