From 5ab16ee55090288afca7ff1c016c0993d8f2a6e5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 28 Oct 2014 10:39:57 -0600 Subject: [PATCH] EFM32: Fix GPIO configuration logic; Add missing board initializatin logic; Fix LED naming --- arch/arm/src/efm32/efm32_gpio.c | 2 +- arch/arm/src/efm32/efm32_start.c | 105 ++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/efm32/efm32_gpio.c b/arch/arm/src/efm32/efm32_gpio.c index 32bc200b08..847520fabc 100644 --- a/arch/arm/src/efm32/efm32_gpio.c +++ b/arch/arm/src/efm32/efm32_gpio.c @@ -266,7 +266,7 @@ static inline void efm32_setmode(uintptr_t base, uint8_t pin, uint8_t mode) regval = getreg32(regaddr); regval &= ~((uint32_t)15 << shift); - regval |= ~((uint32_t)mode << shift); + regval |= (uint32_t)mode << shift; putreg32(regval, regaddr); } diff --git a/arch/arm/src/efm32/efm32_start.c b/arch/arm/src/efm32/efm32_start.c index 655e4e10f2..eab75ae3bb 100644 --- a/arch/arm/src/efm32/efm32_start.c +++ b/arch/arm/src/efm32/efm32_start.c @@ -51,15 +51,23 @@ #include "up_arch.h" #include "up_internal.h" + #include "efm32_config.h" #include "efm32_lowputc.h" #include "efm32_clockconfig.h" #include "efm32_start.h" +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + /**************************************************************************** * Private Function prototypes ****************************************************************************/ +#ifdef CONFIG_ARCH_FPU +static inline void efm32_fpuconfig(void); +#endif #ifdef CONFIG_DEBUG_STACK static void go_os_start(void *pv, unsigned int nbytes) __attribute__ ((naked,no_instrument_function,noreturn)); @@ -89,6 +97,96 @@ static void go_os_start(void *pv, unsigned int nbytes) # define showprogress(c) #endif +/**************************************************************************** + * Name: efm32_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#ifdef CONFIG_ARMV7M_CMNVECTOR + +static inline void efm32_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void efm32_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define efm32_fpuconfig() +#endif + /**************************************************************************** * Name: go_os_start * @@ -149,6 +247,7 @@ void __start(void) /* Configure the uart so that we can get debug output as soon as possible */ efm32_clockconfig(); + efm32_fpuconfig(); efm32_lowsetup(); showprogress('A'); @@ -179,7 +278,6 @@ void __start(void) /* Perform early serial initialization */ up_earlyserialinit(); - showprogress('D'); /* For the case of the separate user-/kernel-space build, perform whatever @@ -193,6 +291,11 @@ void __start(void) showprogress('E'); #endif + /* Initialize onboard resources */ + + efm32_boardinitialize(); + showprogress('F'); + /* Then start NuttX */ showprogress('\r');