LPC17xx now supports FPU needed by LPC1788; LPC17xx can not use Mike's common vectors
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5623 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
32140677f0
commit
d938d49e5a
@ -60,6 +60,7 @@ config ARCH_CHIP_LM
|
||||
config ARCH_CHIP_LPC17XX
|
||||
bool "NXP LPC17xx"
|
||||
select ARCH_CORTEXM3
|
||||
select ARCH_HAVE_CMNVECTOR
|
||||
select ARCH_HAVE_MPU
|
||||
---help---
|
||||
NXP LPC17xx architectures (ARM Cortex-M3)
|
||||
|
@ -35,19 +35,29 @@
|
||||
|
||||
# The start-up, "head", file
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
HEAD_ASRC =
|
||||
else
|
||||
HEAD_ASRC = lpc17_vectors.S
|
||||
endif
|
||||
|
||||
# Common ARM and Cortex-M3 files
|
||||
|
||||
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S \
|
||||
vfork.S
|
||||
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
|
||||
up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c \
|
||||
up_initialstate.c up_interruptcontext.c up_modifyreg8.c \
|
||||
up_modifyreg16.c up_modifyreg32.c up_releasepending.c \
|
||||
up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
|
||||
up_sigdeliver.c up_unblocktask.c up_usestack.c up_doirq.c \
|
||||
up_hardfault.c up_svcall.c up_checkstack.c up_vfork.c
|
||||
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
|
||||
CMN_ASRCS += vfork.S
|
||||
|
||||
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c up_createstack.c
|
||||
CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c
|
||||
CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_modifyreg8.c
|
||||
CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c
|
||||
CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c
|
||||
CMN_CSRCS += up_sigdeliver.c up_unblocktask.c up_usestack.c up_doirq.c
|
||||
CMN_CSRCS += up_hardfault.c up_svcall.c up_checkstack.c up_vfork.c
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
CMN_ASRCS += up_exception.S
|
||||
CMN_CSRCS += up_vectors.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_MEMCPY),y)
|
||||
CMN_ASRCS += up_memcpy.S
|
||||
@ -63,15 +73,24 @@ ifeq ($(CONFIG_ELF),y)
|
||||
CMN_CSRCS += up_elf.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||
CMN_ASRCS += up_fpu.S
|
||||
endif
|
||||
|
||||
# Required LPC17xx files
|
||||
|
||||
CHIP_ASRCS =
|
||||
CHIP_CSRCS = lpc17_allocateheap.c lpc17_clockconfig.c lpc17_clrpend.c \
|
||||
lpc17_gpio.c lpc17_i2c.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c \
|
||||
lpc17_serial.c lpc17_spi.c lpc17_ssp.c lpc17_start.c lpc17_timerisr.c
|
||||
|
||||
CHIP_CSRCS = lpc17_allocateheap.c lpc17_clockconfig.c lpc17_clrpend.c
|
||||
CHIP_CSRCS += lpc17_gpio.c lpc17_i2c.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c
|
||||
CHIP_CSRCS += lpc17_serial.c lpc17_spi.c lpc17_ssp.c lpc17_start.c lpc17_timerisr.c
|
||||
|
||||
# Configuration-dependent LPC17xx files
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
CHIP_ASRCS += lpc17_vectors.S
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_GPIO_IRQ),y)
|
||||
CHIP_CSRCS += lpc17_gpioint.c
|
||||
endif
|
||||
|
@ -42,11 +42,28 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/* Include the memory map and the chip definitions file. Other chip hardware files
|
||||
* should then include this file for the proper setup.
|
||||
*/
|
||||
/* Include the chip capabilities file */
|
||||
|
||||
#include <arch/lpc17xx/chip.h>
|
||||
|
||||
/* If the common ARMv7-M vector handling logic is used, then include the
|
||||
* required vector definitions as well.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7M_CMNVECTOR
|
||||
# if defined(LPC176x)
|
||||
# include "chip/lpc176x_vectors.h"
|
||||
# elif defined(LPC178x)
|
||||
# include "chip/lpc178x_vectors.h"
|
||||
# else
|
||||
# error "No vector file for this LPC17xx family"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Include the memory map file. Other chip hardware files should then include
|
||||
* this file for the proper setup.
|
||||
*/
|
||||
|
||||
#include "chip/lpc17_memorymap.h"
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -53,6 +53,10 @@
|
||||
#include "lpc17_clockconfig.h"
|
||||
#include "lpc17_lowputc.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
# include "nvic.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
@ -83,6 +87,96 @@
|
||||
# define showprogress(c)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_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 lpc17_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 lpc17_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 lpc17_fpuconfig()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -103,6 +197,7 @@ void __start(void)
|
||||
/* Configure the uart so that we can get debug output as soon as possible */
|
||||
|
||||
lpc17_clockconfig();
|
||||
lpc17_fpuconfig();
|
||||
lpc17_lowsetup();
|
||||
showprogress('A');
|
||||
|
||||
|
@ -39,12 +39,14 @@
|
||||
************************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/************************************************************************************************
|
||||
* Preprocessor Definitions
|
||||
************************************************************************************************/
|
||||
|
||||
/* Memory Map:
|
||||
*
|
||||
* 0x0000:0000 - Beginning of FLASH. Address of vectors
|
||||
@ -72,12 +74,16 @@
|
||||
* Global Symbols
|
||||
************************************************************************************************/
|
||||
|
||||
.globl __start
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "lpc17_vectors.S"
|
||||
|
||||
/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */
|
||||
|
||||
#ifndef CONFIG_ARMV7M_CMNVECTOR
|
||||
|
||||
.globl __start
|
||||
|
||||
/************************************************************************************************
|
||||
* Macros
|
||||
************************************************************************************************/
|
||||
@ -208,13 +214,18 @@ lpc17_common:
|
||||
*/
|
||||
|
||||
adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */
|
||||
ite ne /* Next two instructions are condition */
|
||||
ite ne /* Next two instructions are conditional */
|
||||
mrsne r1, msp /* R1=The main stack pointer */
|
||||
mrseq r1, psp /* R1=The process stack pointer */
|
||||
#else
|
||||
mrs r1, msp /* R1=The main stack pointer */
|
||||
#endif
|
||||
|
||||
/* r1 holds the value of the stack pointer AFTER the excption handling logic
|
||||
* pushed the various registers onto the stack. Get r2 = the value of the
|
||||
* stack pointer BEFORE the interrupt modified it.
|
||||
*/
|
||||
|
||||
mov r2, r1 /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
@ -222,6 +233,22 @@ lpc17_common:
|
||||
#else
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Skip over the block of memory reserved for floating pointer register save.
|
||||
* Lazy FPU register saving is used. FPU registers will be saved in this
|
||||
* block only if a context switch occurs (this means, of course, that the FPU
|
||||
* cannot be used in interrupt processing).
|
||||
*/
|
||||
|
||||
sub r1, #(4*SW_FPU_REGS)
|
||||
#endif
|
||||
|
||||
/* Save the the remaining registers on the stack after the registers pushed
|
||||
* by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11,
|
||||
* r14=register values.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
|
||||
#else
|
||||
@ -258,6 +285,25 @@ lpc17_common:
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 1f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch.
|
||||
*
|
||||
* If the FPU is enabled, then we will need to restore FPU registers.
|
||||
* This is not done in normal interrupt save/restore because the cost
|
||||
* is prohibitive. This is only done when switching contexts. A
|
||||
* consequence of this is that floating point operations may not be
|
||||
* performed in interrupt handling logic.
|
||||
*
|
||||
* Here:
|
||||
* r0 = Address of the register save area
|
||||
|
||||
* NOTE: It is a requirement that up_restorefpu() preserve the value of
|
||||
* r0!
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
bl up_restorefpu /* Restore the FPU registers */
|
||||
#endif
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie on the
|
||||
* stack but, rather, are within a TCB structure. We'll have to copy some
|
||||
@ -277,6 +323,9 @@ lpc17_common:
|
||||
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created
|
||||
*
|
||||
* Here:
|
||||
* r1 = Address of the return stack (same as r0)
|
||||
*/
|
||||
1:
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
@ -284,6 +333,23 @@ lpc17_common:
|
||||
#else
|
||||
ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Skip over the block of memory reserved for floating pointer register
|
||||
* save. Then R1 is the address of the HW save area
|
||||
*/
|
||||
|
||||
add r1, #(4*SW_FPU_REGS)
|
||||
#endif
|
||||
|
||||
/* Set up to return from the exception
|
||||
*
|
||||
* Here:
|
||||
* r1 = Address on the target thread's stack position at the start of
|
||||
* the registers saved by hardware
|
||||
* r3 = primask or basepri
|
||||
* r4-r11 = restored register values
|
||||
*/
|
||||
2:
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
|
||||
@ -338,6 +404,7 @@ up_interruptstack:
|
||||
g_intstackbase:
|
||||
.size up_interruptstack, .-up_interruptstack
|
||||
#endif
|
||||
#endif /* CONFIG_ARMV7M_CMNVECTOR */
|
||||
|
||||
/************************************************************************************************
|
||||
* .rodata
|
||||
|
@ -39,16 +39,17 @@ else
|
||||
HEAD_ASRC = stm32_vectors.S
|
||||
endif
|
||||
|
||||
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S \
|
||||
vfork.S
|
||||
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c \
|
||||
up_createstack.c up_mdelay.c up_udelay.c up_exit.c \
|
||||
up_initialize.c up_initialstate.c up_interruptcontext.c \
|
||||
up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
|
||||
up_releasepending.c up_releasestack.c up_reprioritizertr.c \
|
||||
up_schedulesigaction.c up_sigdeliver.c up_systemreset.c \
|
||||
up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c \
|
||||
up_svcall.c up_vfork.c
|
||||
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
|
||||
CMN_ASRCS += vfork.S
|
||||
|
||||
CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.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
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
CMN_ASRCS += up_exception.S
|
||||
@ -72,30 +73,31 @@ CMN_ASRCS += up_fpu.S
|
||||
endif
|
||||
|
||||
CHIP_ASRCS =
|
||||
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c \
|
||||
stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c \
|
||||
stm32_timerisr.c stm32_dma.c stm32_lowputc.c stm32_serial.c \
|
||||
stm32_spi.c stm32_sdio.c stm32_tim.c stm32_i2c.c stm32_waste.c
|
||||
|
||||
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
|
||||
CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c
|
||||
CHIP_CSRCS += stm32_timerisr.c stm32_dma.c stm32_lowputc.c stm32_serial.c
|
||||
CHIP_CSRCS += stm32_spi.c stm32_sdio.c stm32_tim.c stm32_i2c.c stm32_waste.c
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
CHIP_ASRCS += stm32_vectors.S
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV),y)
|
||||
ifeq ($(CONFIG_STM32_USB),y)
|
||||
CMN_CSRCS += stm32_usbdev.c
|
||||
CHIP_CSRCS += stm32_usbdev.c
|
||||
endif
|
||||
ifeq ($(CONFIG_STM32_OTGFS),y)
|
||||
CMN_CSRCS += stm32_otgfsdev.c
|
||||
CHIP_CSRCS += stm32_otgfsdev.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBHOST),y)
|
||||
ifeq ($(CONFIG_STM32_OTGFS),y)
|
||||
CMN_CSRCS += stm32_otgfshost.c
|
||||
CHIP_CSRCS += stm32_otgfshost.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
CHIP_ASRCS += stm32_vectors.S
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_IDLE_CUSTOM),y)
|
||||
CHIP_CSRCS += stm32_idle.c
|
||||
endif
|
||||
|
@ -40,7 +40,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
Loading…
Reference in New Issue
Block a user