Basic support for the EFM32 processor family from Richar Cochran

This commit is contained in:
Gregory Nutt 2014-01-23 07:56:10 -06:00
parent 7ce90ef7e2
commit 7077d99f2f
13 changed files with 1660 additions and 0 deletions

View File

@ -42,6 +42,13 @@ config ARCH_CHIP_DM320
---help---
TI DMS320 DM320 (ARM926EJS)
config ARCH_CHIP_EFM32
bool "Energy Micro"
select ARCH_HAVE_CMNVECTOR
select ARMV7M_CMNVECTOR
---help---
Energy Micro EFM32 microcontrollers (ARM Cortex-M).
config ARCH_CHIP_IMX
bool "Freescale iMX"
select ARCH_ARM920T
@ -210,6 +217,7 @@ config ARCH_CHIP
default "c5471" if ARCH_CHIP_C5471
default "calypso" if ARCH_CHIP_CALYPSO
default "dm320" if ARCH_CHIP_DM320
default "efm32" if ARCH_CHIP_EFM32
default "imx" if ARCH_CHIP_IMX
default "kinetis" if ARCH_CHIP_KINETIS
default "kl" if ARCH_CHIP_KL
@ -346,6 +354,9 @@ endif
if ARCH_CHIP_DM320
source arch/arm/src/dm320/Kconfig
endif
if ARCH_CHIP_EFM32
source arch/arm/src/efm32/Kconfig
endif
if ARCH_CHIP_IMX
source arch/arm/src/imx/Kconfig
endif

View File

@ -0,0 +1,54 @@
/************************************************************************************
* arch/arm/include/efm32/chip.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_INCLUDE_EFM32_CHIP_H
#define __ARCH_ARM_INCLUDE_EFM32_CHIP_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <arch/efm32/irq.h>
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
#define NVIC_SYSH_PRIORITY_MIN 0xe0 /* Bits [7:5] set in minimum priority */
#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Three bits of interrupt priority used */
#endif /* __ARCH_ARM_INCLUDE_EFM32_CHIP_H */

View File

@ -0,0 +1,65 @@
/************************************************************************************
* arch/arm/include/efm32s/irq.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_INCLUDE_EFM32_IRQ_H
#define __ARCH_ARM_INCLUDE_EFM32_IRQ_H
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
#define EFM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */
/* Vector 0: Reset stack pointer value */
/* Vector 1: Reset (not handler as an IRQ) */
#define EFM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
#define EFM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
#define EFM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
#define EFM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
#define EFM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
#define EFM32_IRQ_SVCALL (11) /* Vector 11: SVC call */
#define EFM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
/* Vector 13: Reserved */
#define EFM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
#define EFM32_IRQ_SYSTICK (15) /* Vector 15: System tick */
/* External interrupts (vectors >= 16). These definitions are chip-specific */
#define EFM32_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */
#define ARMV7M_PERIPHERAL_INTERRUPTS 38
#define NR_IRQS (16 + ARMV7M_PERIPHERAL_INTERRUPTS)
#endif /* __ARCH_ARM_INCLUDE_EFM32_IRQ_H */

View File

@ -0,0 +1,52 @@
#
# arch/arm/src/efm32/Kconfig
#
if ARCH_CHIP_EFM32
comment "EFM32 Configuration Options"
config ARCH_CHIP_EFM32_EMLIB_PATH
string "External Energy Micro Sources"
default "/cygdrive/c/energymicro"
---help---
The EFM32 port uses the Energy Micro headers and their
emlib sources. This string defines the include path to
the root directory of the Energy Micro source. That
directory will contain the following sub-directories.
- CMSIS/Include
- Device/EnergyMicro/EFM32LG/Include
- emlib/inc
This string may be either an absolute path, or a path
relative to arch/arm/src.
choice
prompt "EFM32 Chip Selection"
default ARCH_CHIP_EFM32LG990F256
config ARCH_CHIP_EFM32LG232F128
bool "EFM32LG232F128"
select ARCH_CORTEXM3
---help---
This chip is a Leopard Gecko with 128 KB flash
and 32 KB RAM in a QFP64 package
config ARCH_CHIP_EFM32LG990F256
bool "EFM32LG990F256"
select ARCH_CORTEXM3
---help---
This chip is a Leopard Gecko with 256 KB flash
and 32 KB RAM in a BGA112 package.
config ARCH_CHIP_EFM32GG990F1024
bool "EFM32GG990F1024"
select ARCH_CORTEXM3
---help---
This chip is a Giant Gecko with 1024 KB flash
and 128 KB RAM in a BGA112 package.
endchoice
endif

View File

@ -0,0 +1,136 @@
############################################################################
# arch/arm/src/efm32/Make.defs
#
# Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_ARCH_CHIP_EFM32LG232F128),y)
CFLAGS += -DEFM32LG232F128
else ifeq ($(CONFIG_ARCH_CHIP_EFM32LG990F256),y)
CFLAGS += -DEFM32LG990F256
else ifeq ($(CONFIG_ARCH_CHIP_EFM32GG990F1024),y)
CFLAGS += -DEFM32GG990F1024
endif
ifeq (-DEFM32LG, $(findstring -DEFM32LG,$(CFLAGS)))
EM_INCDIR := EFM32LG
SYSTEM_EFM32_C := system_efm32lg.c
else ifeq (-DEFM32GG, $(findstring -DEFM32GG,$(CFLAGS)))
EM_INCDIR := EFM32GG
SYSTEM_EFM32_C := system_efm32gg.c
else
$(error unknown efm32 part)
endif
ext := $(patsubst "%",%,$(strip $(CONFIG_ARCH_CHIP_EFM32_EMLIB_PATH)))
ifeq ($(WINTOOL),y)
CFLAGS += -I"${shell cygpath -w $(ext)/CMSIS/Include}"
CFLAGS += -I"${shell cygpath -w $(ext)/Device/EnergyMicro/$(EM_INCDIR)/Include}"
CFLAGS += -I"${shell cygpath -w $(ext)/emlib/inc}"
else
CFLAGS += -I$(ext)/CMSIS/Include
CFLAGS += -I$(ext)/Device/EnergyMicro/$(EM_INCDIR)/Include
CFLAGS += -I$(ext)/emlib/inc
endif
VPATH += $(ext)/emlib/src
VPATH += $(ext)/Device/EnergyMicro/$(EM_INCDIR)/Source
HEAD_ASRC =
CMN_UASRCS =
CMN_UCSRCS =
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
CMN_ASRCS += up_exception.S
CMN_ASRCS += vfork.S
ifeq ($(CONFIG_ARCH_MEMCPY),y)
CMN_ASRCS += up_memcpy.S
endif
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c
CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c
CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c
CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c
CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c
CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_systemreset.c
CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c
CMN_CSRCS += up_svcall.c up_vfork.c
CMN_CSRCS += up_vectors.c
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c
endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_dispatch.c
CMN_UASRCS += up_signal_handler.S
endif
endif
ifeq ($(CONFIG_DEBUG_STACK),y)
CMN_CSRCS += up_checkstack.c
endif
ifeq ($(CONFIG_ELF),y)
CMN_CSRCS += up_elf.c
endif
ifeq ($(CONFIG_ARCH_FPU),y)
CMN_ASRCS += up_fpu.S
ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y)
CMN_CSRCS += up_copyarmstate.c
endif
endif
CHIP_ASRCS = efm32_vectors.S
CHIP_CSRCS = \
efm32_irq.c \
efm32_start.c \
efm32_timerisr.c \
em_cmu.c \
em_emu.c \
em_gpio.c \
em_usart.c \
$(SYSTEM_EFM32_C)
ifeq ($(CONFIG_DEV_LOWCONSOLE),y)
CHIP_CSRCS += efm32_lowputc.c
endif
ifneq ($(CONFIG_IDLE_CUSTOM),y)
CHIP_CSRCS += efm32_idle.c
endif

54
arch/arm/src/efm32/chip.h Normal file
View File

@ -0,0 +1,54 @@
/************************************************************************************
* arch/arm/src/efm32/chip.h
*
* Copyright (C) 2014 Richard Cochran. All rights reserved.
* Author: Richard Cochran <richardcochran@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_EFM32_CHIP_H
#define __ARCH_ARM_SRC_EFM32_CHIP_H
/************************************************************************************
* Included Files
************************************************************************************/
/*
* Greg says:
*
* This arch/arm/src/stm32/chip.h file was a bad idea that happened a
* long time ago. Right now, I believe that its only required to be
* there to provide the number of interrupt vectors. It is included
* by armv7-m/up_vectors.c where that value is used.
*/
#include <arch/efm32/chip.h>
#endif /* __ARCH_ARM_SRC_EFM32_CHIP_H */

View File

@ -0,0 +1,96 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_idle.c
*
* Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/board/board.h>
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/power/pm.h>
#include <arch/irq.h>
#include "chip.h"
#include "up_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Does the board support an IDLE LED to indicate that the board is in the
* IDLE state?
*/
#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE)
# define BEGIN_IDLE() up_ledon(LED_IDLE)
# define END_IDLE() up_ledoff(LED_IDLE)
#else
# define BEGIN_IDLE()
# define END_IDLE()
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_idle
*
* Description:
* up_idle() is the logic that will be executed when their is no other
* ready-to-run task. This is processor idle time and will continue until
* some interrupt occurs to cause a context switch from the idle task.
*
* Processing in this state may be processor-specific. e.g., this is where
* power management operations might be performed.
*
****************************************************************************/
void up_idle(void)
{
/* Perform IDLE mode power management */
/* Sleep until an interrupt occurs to save power. */
}

View File

@ -0,0 +1,539 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_irq.c
*
* Copyright (C) 2009-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "nvic.h"
#include "ram_vectors.h"
#include "up_arch.h"
#include "os_internal.h"
#include "up_internal.h"
#include "chip.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Get a 32-bit version of the default priority */
#define DEFPRIORITY32 \
(NVIC_SYSH_PRIORITY_DEFAULT << 24 |\
NVIC_SYSH_PRIORITY_DEFAULT << 16 |\
NVIC_SYSH_PRIORITY_DEFAULT << 8 |\
NVIC_SYSH_PRIORITY_DEFAULT)
/* Given the address of a NVIC ENABLE register, this is the offset to
* the corresponding CLEAR ENABLE register.
*/
#define NVIC_ENA_OFFSET (0)
#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE)
/****************************************************************************
* Public Data
****************************************************************************/
volatile uint32_t *current_regs;
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: efm32_dumpnvic
*
* Description:
* Dump some interesting NVIC registers
*
****************************************************************************/
#if defined(CONFIG_DEBUG_IRQ)
static void efm32_dumpnvic(const char *msg, int irq)
{
irqstate_t flags;
flags = irqsave();
lldbg("NVIC (%s, irq=%d):\n", msg, irq);
lldbg(" INTCTRL: %08x VECTAB: %08x\n",
getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
#if 0
lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n",
getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA),
getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE));
#endif
lldbg(" IRQ ENABLE: %08x %08x %08x\n",
getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE),
getreg32(NVIC_IRQ64_95_ENABLE));
lldbg(" SYSH_PRIO: %08x %08x %08x\n",
getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
getreg32(NVIC_SYSH12_15_PRIORITY));
lldbg(" IRQ PRIO: %08x %08x %08x %08x\n",
getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY),
getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY));
lldbg(" %08x %08x %08x %08x\n",
getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY),
getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY));
lldbg(" %08x %08x %08x %08x\n",
getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY),
getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY));
lldbg(" %08x %08x %08x %08x\n",
getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY),
getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY));
lldbg(" %08x\n",
getreg32(NVIC_IRQ64_67_PRIORITY));
irqrestore(flags);
}
#else
# define efm32_dumpnvic(msg, irq)
#endif
/****************************************************************************
* Name: efm32_nmi, efm32_busfault, efm32_usagefault, efm32_pendsv,
* efm32_dbgmonitor, efm32_pendsv, efm32_reserved
*
* Description:
* Handlers for various execptions. None are handled and all are fatal
* error conditions. The only advantage these provided over the default
* unexpected interrupt handler is that they provide a diagnostic output.
*
****************************************************************************/
#ifdef CONFIG_DEBUG
static int efm32_nmi(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! NMI received\n");
PANIC();
return 0;
}
static int efm32_busfault(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS));
PANIC();
return 0;
}
static int efm32_usagefault(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS));
PANIC();
return 0;
}
static int efm32_pendsv(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! PendSV received\n");
PANIC();
return 0;
}
static int efm32_dbgmonitor(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! Debug Monitor receieved\n");
PANIC();
return 0;
}
static int efm32_reserved(int irq, FAR void *context)
{
(void)irqsave();
dbg("PANIC!!! Reserved interrupt\n");
PANIC();
return 0;
}
#endif
/****************************************************************************
* Name: efm32_prioritize_syscall
*
* Description:
* Set the priority of an exception. This function may be needed
* internally even if support for prioritized interrupts is not enabled.
*
****************************************************************************/
#ifdef CONFIG_ARMV7M_USEBASEPRI
static inline void efm32_prioritize_syscall(int priority)
{
uint32_t regval;
/* SVCALL is system handler 11 */
regval = getreg32(NVIC_SYSH8_11_PRIORITY);
regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK;
regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT);
putreg32(regval, NVIC_SYSH8_11_PRIORITY);
}
#endif
/****************************************************************************
* Name: efm32_irqinfo
*
* Description:
* Given an IRQ number, provide the register and bit setting to enable or
* disable the irq.
*
****************************************************************************/
static int efm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
uintptr_t offset)
{
DEBUGASSERT(irq >= EFM32_IRQ_NMI && irq < NR_IRQS);
/* Check for external interrupt */
if (irq >= EFM32_IRQ_INTERRUPTS)
{
if (irq < EFM32_IRQ_INTERRUPTS + 32)
{
*regaddr = (NVIC_IRQ0_31_ENABLE + offset);
*bit = 1 << (irq - EFM32_IRQ_INTERRUPTS);
}
else if (irq < EFM32_IRQ_INTERRUPTS + 64)
{
*regaddr = (NVIC_IRQ32_63_ENABLE + offset);
*bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 32);
}
else if (irq < NR_IRQS)
{
*regaddr = (NVIC_IRQ64_95_ENABLE + offset);
*bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 64);
}
else
{
return ERROR; /* Invalid interrupt */
}
}
/* Handle processor exceptions. Only a few can be disabled */
else
{
*regaddr = NVIC_SYSHCON;
if (irq == EFM32_IRQ_MEMFAULT)
{
*bit = NVIC_SYSHCON_MEMFAULTENA;
}
else if (irq == EFM32_IRQ_BUSFAULT)
{
*bit = NVIC_SYSHCON_BUSFAULTENA;
}
else if (irq == EFM32_IRQ_USAGEFAULT)
{
*bit = NVIC_SYSHCON_USGFAULTENA;
}
else if (irq == EFM32_IRQ_SYSTICK)
{
*regaddr = NVIC_SYSTICK_CTRL;
*bit = NVIC_SYSTICK_CTRL_ENABLE;
}
else
{
return ERROR; /* Invalid or unsupported exception */
}
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_irqinitialize
****************************************************************************/
void up_irqinitialize(void)
{
uint32_t regaddr;
int num_priority_registers;
/* Disable all interrupts */
putreg32(0, NVIC_IRQ0_31_ENABLE);
putreg32(0, NVIC_IRQ32_63_ENABLE);
/* Colorize the interrupt stack for debug purposes */
#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
{
size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
intstack_size);
}
#endif
/*
* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
* vector table that requires special initialization.
*/
#if defined(CONFIG_ARCH_RAMVECTORS)
up_ramvec_initialize();
#endif
/* Set all interrupts (and exceptions) to the default priority */
putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
/* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
* lines that the NVIC supports:
*
* 0 -> 32 interrupt lines, 8 priority registers
* 1 -> 64 " " " ", 16 priority registers
* 2 -> 96 " " " ", 32 priority registers
* ...
*/
num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;
/* Now set all of the interrupt lines to the default priority */
regaddr = NVIC_IRQ0_3_PRIORITY;
while (num_priority_registers--)
{
putreg32(DEFPRIORITY32, regaddr);
regaddr += 4;
}
/* currents_regs is non-NULL only while processing an interrupt */
current_regs = NULL;
/* Attach the SVCall and Hard Fault exception handlers. The SVCall
* exception is used for performing context switches; The Hard Fault
* must also be caught because a SVCall may show up as a Hard Fault
* under certain conditions.
*/
irq_attach(EFM32_IRQ_SVCALL, up_svcall);
irq_attach(EFM32_IRQ_HARDFAULT, up_hardfault);
/* Set the priority of the SVCall interrupt */
#ifdef CONFIG_ARMV7M_USEBASEPRI
efm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif
/* If the MPU is enabled, then attach and enable the Memory Management
* Fault handler.
*/
#ifdef CONFIG_ARMV7M_MPU
irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
up_enable_irq(EFM32_IRQ_MEMFAULT);
#endif
/* Attach all other processor exceptions (except reset and sys tick) */
#ifdef CONFIG_DEBUG
irq_attach(EFM32_IRQ_NMI, efm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
#endif
irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault);
irq_attach(EFM32_IRQ_USAGEFAULT, efm32_usagefault);
irq_attach(EFM32_IRQ_PENDSV, efm32_pendsv);
irq_attach(EFM32_IRQ_DBGMONITOR, efm32_dbgmonitor);
irq_attach(EFM32_IRQ_RESERVED, efm32_reserved);
#endif
efm32_dumpnvic("initial", NR_IRQS);
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */
irqenable();
#endif
}
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* Disable the IRQ specified by 'irq'
*
****************************************************************************/
void up_disable_irq(int irq)
{
uintptr_t regaddr;
uint32_t regval;
uint32_t bit;
if (efm32_irqinfo(irq, &regaddr, &bit, NVIC_CLRENA_OFFSET) == 0)
{
/* Modify the appropriate bit in the register to disable the interrupt.
* For normal interrupts, we need to set the bit in the associated
* Interrupt Clear Enable register. For other exceptions, we need to
* clear the bit in the System Handler Control and State Register.
*/
if (irq >= EFM32_IRQ_INTERRUPTS)
{
putreg32(bit, regaddr);
}
else
{
regval = getreg32(regaddr);
regval &= ~bit;
putreg32(regval, regaddr);
}
}
efm32_dumpnvic("disable", irq);
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* Enable the IRQ specified by 'irq'
*
****************************************************************************/
void up_enable_irq(int irq)
{
uintptr_t regaddr;
uint32_t regval;
uint32_t bit;
if (efm32_irqinfo(irq, &regaddr, &bit, NVIC_ENA_OFFSET) == 0)
{
/* Modify the appropriate bit in the register to enable the interrupt.
* For normal interrupts, we need to set the bit in the associated
* Interrupt Set Enable register. For other exceptions, we need to
* set the bit in the System Handler Control and State Register.
*/
if (irq >= EFM32_IRQ_INTERRUPTS)
{
putreg32(bit, regaddr);
}
else
{
regval = getreg32(regaddr);
regval |= bit;
putreg32(regval, regaddr);
}
}
efm32_dumpnvic("enable", irq);
}
/****************************************************************************
* Name: up_ack_irq
*
* Description:
* Acknowledge the IRQ
*
****************************************************************************/
void up_ack_irq(int irq)
{
}
/****************************************************************************
* Name: up_prioritize_irq
*
* Description:
* Set the priority of an IRQ.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQPRIO
int up_prioritize_irq(int irq, int priority)
{
uint32_t regaddr;
uint32_t regval;
int shift;
DEBUGASSERT(irq >= EFM32_IRQ_MEMFAULT && irq < NR_IRQS &&
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
if (irq < EFM32_IRQ_INTERRUPTS)
{
/* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority
* registers (0-3 are invalid)
*/
regaddr = NVIC_SYSH_PRIORITY(irq);
irq -= 4;
}
else
{
/* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */
irq -= EFM32_IRQ_INTERRUPTS;
regaddr = NVIC_IRQ_PRIORITY(irq);
}
regval = getreg32(regaddr);
shift = ((irq & 3) << 3);
regval &= ~(0xff << shift);
regval |= (priority << shift);
putreg32(regval, regaddr);
efm32_dumpnvic("prioritize", irq);
return OK;
}
#endif

View File

@ -0,0 +1,111 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_lowputc.c
*
* Copyright (C) 2014 Richard Cochran. All rights reserved.
* Author: Richard Cochran <richardcochran@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "up_internal.h"
#include "efm32_lowputc.h"
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BAUDRATE 115200
#if defined UART_PRESENT
#if UART_COUNT > 1
#define RXPIN 10
#define RXPORT gpioPortB
#define TXPIN 9
#define TXPORT gpioPortB
#define UART UART1
#define UART_CLOCK cmuClock_UART1
#define UART_LOC USART_ROUTE_LOCATION_LOC2
#else
#error unknown efm32 part
#endif
#elif defined USART_PRESENT
#define RXPIN 11
#define RXPORT gpioPortE
#define TXPIN 10
#define TXPORT gpioPortE
#define UART USART0
#define UART_CLOCK cmuClock_USART0
#define UART_LOC USART_ROUTE_LOCATION_LOC0
#endif /* USART_PRESENT */
/****************************************************************************
* Public Functions
****************************************************************************/
void efm32_lowsetup(void)
{
USART_InitAsync_TypeDef settings = USART_INITASYNC_DEFAULT;
CMU_ClockEnable(UART_CLOCK, true);
GPIO_PinModeSet(TXPORT, TXPIN, gpioModePushPull, 1);
GPIO_PinModeSet(RXPORT, RXPIN, gpioModeInput, 0);
settings.baudrate = BAUDRATE;
USART_InitAsync(UART, &settings);
UART->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | UART_LOC;
}
void up_lowputc(char c)
{
while (!(UART->STATUS & USART_STATUS_TXBL));
UART->TXDATA = c;
}
void up_putc(char c)
{
/* Convert LF into CRLF. */
if (c == '\n')
up_lowputc('\r');
up_lowputc(c);
}

View File

@ -0,0 +1,55 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_lowputc.h
*
* Copyright (C) 2014 Richard Cochran. All rights reserved.
* Author: Richard Cochran <richardcochran@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_EFM32_STM32_LOWPUTC_H
#define __ARCH_ARM_SRC_EFM32_STM32_LOWPUTC_H
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_DEV_LOWCONSOLE
void efm32_lowsetup(void);
#else
static inline void efm32_lowsetup(void)
{
}
#endif
#endif

View File

@ -0,0 +1,223 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_start.c
*
* Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/init.h>
#include <arch/board/board.h>
#include <arch/efm32/chip.h>
#include "up_arch.h"
#include "up_internal.h"
#include "efm32_lowputc.h"
#include "em_device.h"
#include "em_cmu.h"
/****************************************************************************
* Private Function prototypes
****************************************************************************/
#ifdef CONFIG_DEBUG_STACK
static void go_os_start(void *pv, unsigned int nbytes)
__attribute__ ((naked,no_instrument_function,noreturn));
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: showprogress
*
* Description:
* Print a character on the UART to show boot status.
*
****************************************************************************/
#ifdef CONFIG_DEBUG
# define showprogress(c) up_lowputc(c)
#else
# define showprogress(c)
#endif
/****************************************************************************
* Name: go_os_start
*
* Description:
* Set the IDLE stack to the
*
****************************************************************************/
#ifdef CONFIG_DEBUG_STACK
static void go_os_start(void *pv, unsigned int nbytes)
{
/* Set the IDLE stack to the stack coloration value then jump to
* os_start(). We take extreme care here because were currently
* executing on this stack.
*
* We want to avoid sneak stack access generated by the compiler.
*/
__asm__ __volatile__
(
"\tmov r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */
"\tbeq 2f\n" /* (should not happen) */
"\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */
"\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */
"\tmovt r2, #0xdead\n"
"1:\n" /* Top of the loop */
"\tsub r1, r1, #1\n" /* R1 nwords-- */
"\tcmp r1, #0\n" /* Check (nwords == 0) */
"\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */
"\tbne 1b\n" /* Bottom of the loop */
"2:\n"
"\tmov r14, #0\n" /* LR = return address (none) */
"\tb os_start\n" /* Branch to os_start */
);
}
#endif
static void efm32_clockconfig(void)
{
/* Devices boots with 14 MHz HFRCO as the HFCLK source. */
/* Enable the GPIO clock. */
CMU_ClockEnable(cmuClock_GPIO, true);
}
static void efm32_gpioinit(void)
{
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: _start
*
* Description:
* This is the reset entry point.
*
****************************************************************************/
void __start(void)
{
const uint32_t *src;
uint32_t *dest;
/* Configure the uart so that we can get debug output as soon as possible */
efm32_clockconfig();
efm32_lowsetup();
efm32_gpioinit();
showprogress('A');
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*/
for (dest = &_sbss; dest < &_ebss; )
{
*dest++ = 0;
}
showprogress('B');
/* Move the initialized data section from his temporary holding spot in
* FLASH into the correct place in SRAM. The correct place in SRAM is
* give by _sdata and _edata. The temporary location is in FLASH at the
* end of all of the other read-only data (.text, .rodata) at _eronly.
*/
for (src = &_eronly, dest = &_sdata; dest < &_edata; )
{
*dest++ = *src++;
}
showprogress('C');
/* Perform early serial initialization */
#ifdef USE_EARLYSERIALINIT
up_earlyserialinit();
#endif
showprogress('D');
/* For the case of the separate user-/kernel-space build, perform whatever
* platform specific initialization of the user memory is required.
* Normally this just means initializing the user space .data and .bss
* segments.
*/
#ifdef CONFIG_NUTTX_KERNEL
efm32_userspace();
showprogress('E');
#endif
/* Initialize onboard resources */
efm32_boardinitialize();
showprogress('F');
/* Then start NuttX */
showprogress('\r');
showprogress('\n');
#ifdef CONFIG_DEBUG_STACK
/* Set the IDLE stack to the coloration value and jump into os_start() */
go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE);
#else
/* Call os_start() */
os_start();
/* Shoulnd't get here */
for(;;);
#endif
}

View File

@ -0,0 +1,143 @@
/****************************************************************************
* arch/arm/src/efm32/efm32_timerisr.c
*
* Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <time.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "nvic.h"
#include "clock_internal.h"
#include "up_internal.h"
#include "up_arch.h"
#include "chip.h"
/****************************************************************************
* Definitions
****************************************************************************/
/* The desired timer interrupt frequency is provided by the definition
* CLK_TCK (see include/time.h). CLK_TCK defines the desired number of
* system clock ticks per second. That value is a user configurable setting
* that defaults to 100 (100 ticks per second = 10 MS interval).
*/
#define EFM32_HCLK_FREQUENCY 14000000
#define SYSTICK_RELOAD ((EFM32_HCLK_FREQUENCY / CLK_TCK) - 1)
/* The size of the reload field is 24 bits. Verify that the reload value
* will fit in the reload register.
*/
#if SYSTICK_RELOAD > 0x00ffffff
# error SYSTICK_RELOAD exceeds the range of the RELOAD register
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
* Function: up_timerisr
*
* Description:
* The timer ISR will perform a variety of services for various portions
* of the systems.
*
****************************************************************************/
int up_timerisr(int irq, uint32_t *regs)
{
/* Process timer interrupt */
sched_process_timer();
return 0;
}
/****************************************************************************
* Function: up_timerinit
*
* Description:
* This function is called during start-up to initialize
* the timer interrupt.
*
****************************************************************************/
void up_timerinit(void)
{
uint32_t regval;
/* Set the SysTick interrupt to the default priority */
regval = getreg32(NVIC_SYSH12_15_PRIORITY);
regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK;
regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT);
putreg32(regval, NVIC_SYSH12_15_PRIORITY);
/* Make sure that the SYSTICK clock source is set correctly */
/* Configure SysTick to interrupt at the requested rate */
putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD);
/* Attach the timer interrupt vector */
(void)irq_attach(EFM32_IRQ_SYSTICK, (xcpt_t)up_timerisr);
/* Enable SysTick interrupts */
putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE|NVIC_SYSTICK_CTRL_TICKINT|NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL);
/* And enable the timer interrupt */
up_enable_irq(EFM32_IRQ_SYSTICK);
}

View File

@ -0,0 +1,121 @@
/************************************************************************************
* arch/arm/src/efm32/efm32_vectors.S
*
* Copyright (C) 2009-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "chip.h"
#include "exc_return.h"
/************************************************************************************
* Configuration
************************************************************************************/
/************************************************************************************
* Preprocessor Definitions
************************************************************************************/
/* Configuration ********************************************************************/
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
/* In kernel mode without an interrupt stack, this interrupt handler will set the
* MSP to the stack pointer of the interrupted thread. If the interrupted thread
* was a privileged thread, that will be the MSP otherwise it will be the PSP. If
* the PSP is used, then the value of the MSP will be invalid when the interrupt
* handler returns because it will be a pointer to an old position in the
* unprivileged stack. Then when the high priority interrupt occurs and uses this
* stale MSP, there will most likely be a system failure.
*
* If the interrupt stack is selected, on the other hand, then the interrupt
* handler will always set the the MSP to the interrupt stack. So when the high
* priority interrupt occurs, it will either use the MSP of the last privileged
* thread to run or, in the case of the nested interrupt, the interrupt stack if
* no privileged task has run.
*/
# if defined(CONFIG_NUTTX_KERNEL) && CONFIG_ARCH_INTERRUPTSTACK < 4
# error Interrupt stack must be used with high priority interrupts in kernel mode
# endif
/* Use the the BASEPRI to control interrupts is required if nested, high
* priority interrupts are supported.
*/
# ifndef CONFIG_ARMV7M_USEBASEPRI
# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT
# endif
#endif
#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4)
#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE)
/************************************************************************************
* Global Symbols
************************************************************************************/
.syntax unified
.thumb
.file "efm32_vectors.S"
/*
* The efm32 chips all use the common ARMv7 interrupt vectoring.
* (see arch/arm/src/armv7-m/up_vectors.S)
*/
/************************************************************************************
* .rodata
************************************************************************************/
.section .rodata, "a"
/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end
* of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS
* and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that
* the system boots on and, eventually, becomes the idle, do nothing task that runs
* only when there is nothing else to run. The heap continues from there until the
* end of memory. See g_idle_topstack below.
*/
.globl g_idle_topstack
.type g_idle_topstack, object
g_idle_topstack:
.word HEAP_BASE
.size g_idle_topstack, .-g_idle_topstack
.end