Merge pull request #1245 from stevew817/master

[Silicon Labs] Bring EFM32 HAL up to date
pull/1248/merge
Martin Kojtal 2015-07-20 09:46:13 +02:00
commit a68b724d07
21 changed files with 110 additions and 124 deletions

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20020000
; <h> Heap Configuration

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20020000
; <h> Heap Configuration

View File

@ -8,7 +8,7 @@ LR_IROM1 0x00000000 0x00010000 { ; load region size_region
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000080 0x00001F80 { ; RW data
RW_IRAM1 0x20000098 0x00001F68 { ; RW data
.ANY (+RW +ZI)
}
}

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20002000
; <h> Heap Configuration

View File

@ -16,8 +16,8 @@ MEMORY
/* 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.

View File

@ -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

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20008000
; <h> Heap Configuration

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20008000
; <h> Heap Configuration

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20008000
; <h> Heap Configuration

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20008000
; <h> Heap Configuration

View File

@ -33,7 +33,7 @@ Stack_Size EQU 0x00000200
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20001000
; <h> Heap Configuration

View File

@ -103,7 +103,7 @@ typedef enum {
PullDown = InputPullDown,
OpenDrain = WiredAnd,
PullNone = PushPull,
PullDefault = PullUp
PullDefault = PushPull
} PinMode;
#ifdef __cplusplus

View File

@ -102,7 +102,7 @@ typedef enum {
PullDown = InputPullDown,
OpenDrain = WiredAnd,
PullNone = PushPull,
PullDefault = PullUp
PullDefault = PushPull
} PinMode;
#ifdef __cplusplus

View File

@ -102,7 +102,7 @@ typedef enum {
PullDown = InputPullDown,
OpenDrain = WiredAnd,
PullNone = PushPull,
PullDefault = PullUp
PullDefault = PushPull
} PinMode;
#ifdef __cplusplus

View File

@ -102,7 +102,7 @@ typedef enum {
PullDown = InputPullDown,
OpenDrain = WiredAnd,
PullNone = PushPull,
PullDefault = PullUp
PullDefault = PushPull
} PinMode;
#ifdef __cplusplus

View File

@ -102,7 +102,7 @@ typedef enum {
PullDown = InputPullDown,
OpenDrain = WiredAnd,
PullNone = PushPull,
PullDefault = PullUp
PullDefault = PushPull
} PinMode;
#ifdef __cplusplus

View File

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

View File

@ -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);
}
@ -171,7 +172,7 @@ static void GPIOINT_IRQDispatcher(uint32_t iflags)
while(iflags) {
irqIdx = GPIOINT_MASK2IDX(iflags);
/* clear flag*/
/* clear flag */
iflags &= ~(1 << irqIdx);
/* call user callback */
@ -188,13 +189,12 @@ static void GPIOINT_IRQDispatcher(uint32_t iflags)
void GPIO_EVEN_IRQHandler(void)
{
uint32_t iflags;
/* Get all even interrupts. */
/* Get all even interrupts */
iflags = GPIO_IntGetEnabled() & 0x00005555;
/* Clean only even interrupts. */
GPIO_IntClear(iflags);
/* Clean only even interrupts*/
GPIO_IntClear(iflags);
GPIOINT_IRQDispatcher(iflags);
}
@ -209,12 +209,11 @@ void GPIO_ODD_IRQHandler(void)
{
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);
}

View File

@ -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

View File

@ -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
}

View File

@ -977,7 +977,7 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
/* 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. */