LPC17xx platform for Cortex M port

This commit is contained in:
Natie van Rooyen
2012-10-23 14:23:34 +02:00
parent 6f34e08e2f
commit 648d35dbe6
18 changed files with 7094 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,844 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H__
#define __CORE_CMFUNC_H__
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_CONTROL(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_CONTROL(uint32_t control);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_IPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_APSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_xPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PSP(uint32_t topOfProcStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_MSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_MSP(uint32_t topOfMainStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PRIMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PRIMASK(uint32_t priMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_BASEPRI(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_BASEPRI(uint32_t basePri);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_FAULTMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_FAULTMASK(uint32_t faultMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & 1);
}
#endif /* __ARMCC_VERSION */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
#if defined (__ICCARM__)
#include <intrinsics.h> /* IAR Intrinsics */
#endif
#pragma diag_suppress=Pe940
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_irq __enable_interrupt
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_irq __disable_interrupt
/* intrinsic unsigned long __get_CONTROL( void ); (see intrinsic.h) */
/* intrinsic void __set_CONTROL( unsigned long ); (see intrinsic.h) */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
static uint32_t __get_IPSR(void)
{
__ASM("mrs r0, ipsr");
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
static uint32_t __get_APSR(void)
{
__ASM("mrs r0, apsr");
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
static uint32_t __get_xPSR(void)
{
__ASM("mrs r0, psr"); // assembler does not know "xpsr"
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
static uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
static void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
static uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
static void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
}
/* intrinsic unsigned long __get_PRIMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_PRIMASK( unsigned long ); (see intrinsic.h) */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __enable_fault_irq(void)
{
__ASM ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __disable_fault_irq(void)
{
__ASM ("cpsid f");
}
/* intrinsic unsigned long __get_BASEPRI( void ); (see intrinsic.h) */
/* intrinsic void __set_BASEPRI( unsigned long ); (see intrinsic.h) */
/* intrinsic unsigned long __get_FAULTMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_FAULTMASK(unsigned long); (see intrinsic.h) */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
__ASM("vmrs r0, fpscr");
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM("vmsr fpscr, r0");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile ("MRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H__ */

View File

@@ -0,0 +1,775 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H__
#define __CORE_CMINSTR_H__
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern uint32_t __REV16(uint32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern int32_t __REVSH(int32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
extern void __CLREX(void);
#else /* (__ARMCC_VERSION >= 400000) */
#define __CLREX __clrex
#endif /* __ARMCC_VERSION */
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
#include <intrinsics.h> /* IAR Intrinsics */
#pragma diag_suppress=Pe940
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __no_operation
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
static __INLINE void __WFI(void)
{
__ASM ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
static __INLINE void __WFE(void)
{
__ASM ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
static __INLINE void __SEV(void)
{
__ASM ("sev");
}
/* intrinsic void __ISB(void) (see intrinsics.h) */
/* intrinsic void __DSB(void) (see intrinsics.h) */
/* intrinsic void __DMB(void) (see intrinsics.h) */
/* intrinsic uint32_t __REV(uint32_t value) (see intrinsics.h) */
/* intrinsic __SSAT (see intrinsics.h) */
/* intrinsic __USAT (see intrinsics.h) */
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __REV16(uint32_t value)
{
__ASM("rev16 r0, r0");
}
/* intrinsic uint32_t __REVSH(uint32_t value) (see intrinsics.h */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
static uint8_t __LDREXB(volatile uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
static uint16_t __LDREXH(volatile uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
/* intrinsic unsigned long __LDREX(unsigned long *) (see intrinsics.h) */
static uint32_t __LDREXW(volatile uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
/* intrinsic unsigned long __STREX(unsigned long, unsigned long) (see intrinsics.h )*/
static uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
static __INLINE void __CLREX(void)
{
__ASM ("clrex");
}
/* intrinsic unsigned char __CLZ( unsigned long ) (see intrinsics.h) */
#endif /* (__CORTEX_M >= 0x03) */
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H__ */

View File

@@ -0,0 +1,64 @@
/**************************************************************************//**
* @file system_LPC17xx.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC17xx Device Series
* @version V1.02
* @date 08. September 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC17xx_H
#define __SYSTEM_LPC17xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC17xx_H */

View File

@@ -0,0 +1,339 @@
/**************************************************************************//**
* @file core_cm3.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V2.00
* @date 13. September 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ########################## Core Instruction Access ######################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __CLREX(void)
{
clrex
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
/* ########################### Core Function Access ########################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_IPSR(void)
{
mrs r0, ipsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_APSR(void)
{
mrs r0, apsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_xPSR(void)
{
mrs r0, xpsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask Register.
\return Fault Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set the Fault Mask
This function assigns the given value to the Fault Mask Register.
\param [in] faultMask Fault Mask value value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif

View File

@@ -0,0 +1,532 @@
/**************************************************************************//**
* @file system_LPC17xx.c
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
* for the NXP LPC17xx Device Series
* @version V1.08
* @date 12. May 2010
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
#include "LPC17xx.h"
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
// <h> System Controls and Status Register (SCS)
// <o1.4> OSCRANGE: Main Oscillator Range Select
// <0=> 1 MHz to 20 MHz
// <1=> 15 MHz to 24 MHz
// <e1.5> OSCEN: Main Oscillator Enable
// </e>
// </h>
//
// <h> Clock Source Select Register (CLKSRCSEL)
// <o2.0..1> CLKSRC: PLL Clock Source Selection
// <0=> Internal RC oscillator
// <1=> Main oscillator
// <2=> RTC oscillator
// </h>
//
// <e3> PLL0 Configuration (Main PLL)
// <h> PLL0 Configuration Register (PLL0CFG)
// <i> F_cco0 = (2 * M * F_in) / N
// <i> F_in must be in the range of 32 kHz to 50 MHz
// <i> F_cco0 must be in the range of 275 MHz to 550 MHz
// <o4.0..14> MSEL: PLL Multiplier Selection
// <6-32768><#-1>
// <i> M Value
// <o4.16..23> NSEL: PLL Divider Selection
// <1-256><#-1>
// <i> N Value
// </h>
// </e>
//
// <e5> PLL1 Configuration (USB PLL)
// <h> PLL1 Configuration Register (PLL1CFG)
// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
// <i> F_cco1 = F_osc * M * 2 * P
// <i> F_cco1 must be in the range of 156 MHz to 320 MHz
// <o6.0..4> MSEL: PLL Multiplier Selection
// <1-32><#-1>
// <i> M Value (for USB maximum value is 4)
// <o6.5..6> PSEL: PLL Divider Selection
// <0=> 1
// <1=> 2
// <2=> 4
// <3=> 8
// <i> P Value
// </h>
// </e>
//
// <h> CPU Clock Configuration Register (CCLKCFG)
// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0
// <1-256><#-1>
// </h>
//
// <h> USB Clock Configuration Register (USBCLKCFG)
// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL0
// <0-15>
// <i> Divide is USBSEL + 1
// </h>
//
// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 6
// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 6
// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 6
// </h>
//
// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
// <0=> Pclk = Cclk / 4
// <1=> Pclk = Cclk
// <2=> Pclk = Cclk / 2
// <3=> Pclk = Hclk / 8
// </h>
//
// <h> Power Control for Peripherals Register (PCONP)
// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable
// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable
// <o11.3> PCUART0: UART 0 power/clock enable
// <o11.4> PCUART1: UART 1 power/clock enable
// <o11.6> PCPWM1: PWM 1 power/clock enable
// <o11.7> PCI2C0: I2C interface 0 power/clock enable
// <o11.8> PCSPI: SPI interface power/clock enable
// <o11.9> PCRTC: RTC power/clock enable
// <o11.10> PCSSP1: SSP interface 1 power/clock enable
// <o11.12> PCAD: A/D converter power/clock enable
// <o11.13> PCCAN1: CAN controller 1 power/clock enable
// <o11.14> PCCAN2: CAN controller 2 power/clock enable
// <o11.15> PCGPIO: GPIOs power/clock enable
// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable
// <o11.17> PCMC: Motor control PWM power/clock enable
// <o11.18> PCQEI: Quadrature encoder interface power/clock enable
// <o11.19> PCI2C1: I2C interface 1 power/clock enable
// <o11.21> PCSSP0: SSP interface 0 power/clock enable
// <o11.22> PCTIM2: Timer 2 power/clock enable
// <o11.23> PCTIM3: Timer 3 power/clock enable
// <o11.24> PCUART2: UART 2 power/clock enable
// <o11.25> PCUART3: UART 3 power/clock enable
// <o11.26> PCI2C2: I2C interface 2 power/clock enable
// <o11.27> PCI2S: I2S interface power/clock enable
// <o11.29> PCGPDMA: GP DMA function power/clock enable
// <o11.30> PCENET: Ethernet block power/clock enable
// <o11.31> PCUSB: USB interface power/clock enable
// </h>
//
// <h> Clock Output Configuration Register (CLKOUTCFG)
// <o12.0..3> CLKOUTSEL: Selects clock source for CLKOUT
// <0=> CPU clock
// <1=> Main oscillator
// <2=> Internal RC oscillator
// <3=> USB clock
// <4=> RTC oscillator
// <o12.4..7> CLKOUTDIV: Selects clock divider for CLKOUT
// <1-16><#-1>
// <o12.8> CLKOUT_EN: CLKOUT enable control
// </h>
//
// </e>
*/
#define CLOCK_SETUP 1
#define SCS_Val 0x00000020
#define CLKSRCSEL_Val 0x00000001
#define PLL0_SETUP 1
#define PLL0CFG_Val 0x00050063
#define PLL1_SETUP 1
#define PLL1CFG_Val 0x00000023
#define CCLKCFG_Val 0x00000003
#define USBCLKCFG_Val 0x00000000
#define PCLKSEL0_Val 0x00000000
#define PCLKSEL1_Val 0x00000000
#define PCONP_Val 0x042887DE
#define CLKOUTCFG_Val 0x00000000
/*--------------------- Flash Accelerator Configuration ----------------------
//
// <e> Flash Accelerator Configuration
// <o1.12..15> FLASHTIM: Flash Access Time
// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
// <5=> 6 CPU clocks (for any CPU clock)
// </e>
*/
#define FLASH_SETUP 0
#define FLASHCFG_Val 0x00004000
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
/*----------------------------------------------------------------------------
Check the register settings
*----------------------------------------------------------------------------*/
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
/* Clock Configuration -------------------------------------------------------*/
#if (CHECK_RSVD((SCS_Val), ~0x00000030))
#error "SCS: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
#error "CLKSRCSEL: Value out of range!"
#endif
#if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))
#error "PLL0CFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
#error "PLL1CFG: Invalid values of reserved bits!"
#endif
#if (PLL0_SETUP) /* if PLL0 is used */
#if (CCLKCFG_Val < 2) /* CCLKSEL must be greater then 1 */
#error "CCLKCFG: CCLKSEL must be greater then 1 if PLL0 is used!"
#endif
#endif
#if (CHECK_RANGE((CCLKCFG_Val), 2, 255))
#error "CCLKCFG: Value out of range!"
#endif
#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
#error "USBCLKCFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))
#error "PCLKSEL0: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))
#error "PCLKSEL1: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCONP_Val), 0x10100821))
#error "PCONP: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
#error "CLKOUTCFG: Invalid values of reserved bits!"
#endif
/* Flash Accelerator Configuration -------------------------------------------*/
#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000))
#error "FLASHCFG: Invalid values of reserved bits!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define XTAL (12000000UL) /* Oscillator frequency */
#define OSC_CLK ( XTAL) /* Main oscillator frequency */
#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
/* F_cco0 = (2 * M * F_in) / N */
#define __M (((PLL0CFG_Val ) & 0x7FFF) + 1)
#define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1)
#define __FCCO(__F_IN) ((2/*ULL*/ * __M * __F_IN) / __N)
#define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1)
/* Determine core clock frequency according to settings */
#if (PLL0_SETUP)
#if ((CLKSRCSEL_Val & 0x03) == 1)
#define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)
#elif ((CLKSRCSEL_Val & 0x03) == 2)
#define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)
#else
#define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)
#endif
#else
#if ((CLKSRCSEL_Val & 0x03) == 1)
#define __CORE_CLK (OSC_CLK / __CCLK_DIV)
#elif ((CLKSRCSEL_Val & 0x03) == 2)
#define __CORE_CLK (RTC_CLK / __CCLK_DIV)
#else
#define __CORE_CLK (IRC_OSC / __CCLK_DIV)
#endif
#endif
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
/* Determine clock frequency according to clock register values */
if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */
switch (LPC_SC->CLKSRCSEL & 0x03) {
case 0: /* Int. RC oscillator => PLL0 */
case 3: /* Reserved, default to Int. RC */
SystemCoreClock = (IRC_OSC *
((2/*ULL*/ * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
case 1: /* Main oscillator => PLL0 */
SystemCoreClock = (OSC_CLK *
((2/*ULL*/ * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
case 2: /* RTC oscillator => PLL0 */
SystemCoreClock = (RTC_CLK *
((2/*ULL*/ * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
}
} else {
switch (LPC_SC->CLKSRCSEL & 0x03) {
case 0: /* Int. RC oscillator => PLL0 */
case 3: /* Reserved, default to Int. RC */
SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
case 1: /* Main oscillator => PLL0 */
SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
case 2: /* RTC oscillator => PLL0 */
SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
}
}
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#if (CLOCK_SETUP) /* Clock Setup */
LPC_SC->SCS = SCS_Val;
if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */
while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */
}
LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */
LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */
LPC_SC->PCLKSEL1 = PCLKSEL1_Val;
LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */
#if (PLL0_SETUP)
LPC_SC->PLL0CFG = PLL0CFG_Val; /* configure PLL0 */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0 */
LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */
#endif
#if (PLL1_SETUP)
LPC_SC->PLL1CFG = PLL1CFG_Val;
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */
LPC_SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8))));/* Wait for PLLC1_STAT & PLLE1_STAT */
#else
LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */
#endif
LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */
#endif
#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & ~0x0000F000) | FLASHCFG_Val;
#endif
}

View File

@@ -0,0 +1,95 @@
ifeq ($(TARGET_NAME),)
TARGET_NAME=boot
endif
ifeq ($(ATOMTHREADS),)
ATOMTHREADS = $(shell pwd)/../../
endif
ifeq ($(TEST_NAME),)
TEST_NAME = kern1
endif
CC = arm-none-eabi-gcc
LN = arm-none-eabi-gcc
AS = arm-none-eabi-gcc
CFLAGS := $(CFLAGS) -O3 -Os -g3 -Wall -c -mcpu=cortex-m3 -mthumb
AFLAGS := $(AFLAGS) -O3 -Os -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -mcpu=cortex-m3 -mthumb
LFLAGS := $(LFLAGS) -O3 -Os -Wall -mcpu=cortex-m3 -mthumb -Wl,-Map=system.map -Tsystem.ld
CDEFS := $(CDEFS) -DATOMTHREADS_TEST='"$(TEST_NAME)"'
ADEFS := $(ADEFS) -D__thumb2__ -DARM_RDI_MONITOR
LLIBS := $(LLIBS)
SRCS := $(SRCS) \
./CMSISv2p00_LPC17xx/src/core_cm3.c \
./CMSISv2p00_LPC17xx/src/system_LPC17xx.c \
./drivers/lpc17xx_uart.c \
startup.c \
modules.c \
$(ATOMTHREADS)/tests/$(TEST_NAME).c \
main.c \
ASMS := $(ASMS) \
INCLUDES := $(INCLUDES) \
-I./CMSISv2p00_LPC17xx/inc \
-I$(ATOMTHREADS)
include $(ATOMTHREADS)/ports/cortex_m/Makefile
OBJS = $(SRCS:.c=.o) $(ASMS:.S=.o)
include ../rules.mk
run_test: clean all
cp boot.bin bin/$(TEST_NAME).bin
all_tests:
echo "Starting atomthreads test suite"
make run_test "TEST_NAME=mutex1"
make run_test "TEST_NAME=mutex2"
make run_test "TEST_NAME=mutex3"
make run_test "TEST_NAME=mutex4"
make run_test "TEST_NAME=mutex5"
make run_test "TEST_NAME=mutex6"
make run_test "TEST_NAME=mutex7"
make run_test "TEST_NAME=mutex8"
make run_test "TEST_NAME=mutex9"
make run_test "TEST_NAME=kern1"
make run_test "TEST_NAME=kern2"
make run_test "TEST_NAME=kern3"
make run_test "TEST_NAME=kern4"
make run_test "TEST_NAME=timer1"
make run_test "TEST_NAME=timer2"
make run_test "TEST_NAME=timer3"
make run_test "TEST_NAME=timer4"
make run_test "TEST_NAME=timer5"
make run_test "TEST_NAME=timer6"
make run_test "TEST_NAME=timer7"
make run_test "TEST_NAME=queue1"
make run_test "TEST_NAME=queue2"
make run_test "TEST_NAME=queue3"
make run_test "TEST_NAME=queue4"
make run_test "TEST_NAME=queue5"
make run_test "TEST_NAME=queue6"
make run_test "TEST_NAME=queue7"
make run_test "TEST_NAME=queue8"
make run_test "TEST_NAME=queue9"
make run_test "TEST_NAME=sem1"
make run_test "TEST_NAME=sem2"
make run_test "TEST_NAME=sem3"
make run_test "TEST_NAME=sem4"
make run_test "TEST_NAME=sem5"
make run_test "TEST_NAME=sem6"
make run_test "TEST_NAME=sem7"
make run_test "TEST_NAME=sem8"
make run_test "TEST_NAME=sem9"

View File

@@ -0,0 +1,153 @@
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex1...
mutex1 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex2...
mutex2 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex3...
mutex3 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex5...
mutex5 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex6...
mutex6 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex7...
mutex7 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex8...
mutex8 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex9...
mutex9 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting kern1...
kern1 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting kern2...
kern2 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting kern3...
kern3 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting kern4...
kern4 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer1...
timer1 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer2...
timer2 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer3...
timer3 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer5...
timer5 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer6...
timer6 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer7...
timer7 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue1...
queue1 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue2...
queue2 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue3...
queue3 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue4...
queue4 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue5...
queue5 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue6...
queue6 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue7...
queue7 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue8...
queue8 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting queue9...
queue9 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem1...
sem1 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem2...
sem2 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem3...
sem3 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem5...
sem5 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem6...
sem6 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem7...
sem7 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem8...
sem8 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem9...
sem9 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting mutex4...
mutex4 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting sem4...
sem4 PASS
LPC17xx SystemCoreClock = 100000000
Atomthreads starting timer4...
timer4 PASS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,166 @@
/**************************************************************************//**
* @file lpc17xx_uart.c
* @brief Drivers for UART peripheral in lpc17xx.
* @version 1.0
* @date 18. Nov. 2010
*
* @note
* Copyright (C) 2010 NXP Semiconductors(NXP). All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
******************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include "lpc17xx_uart.h"
#include "lpc17xx.h"
/**
* @brief Initializes the UART0.
*
* @param baudrate: Specifies the baud rate
* @retval None
*/
void LPC17xx_UART_Init(uint32_t baudrate)
{
uint32_t Fdiv;
uint32_t pclkdiv, pclk;
/***/
LPC_PINCON->PINSEL0 &= ~0x000000F0;
LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 and TxD0 */
/* PCLK_UART0=CCLK/2 */
//**LPC_SC->PCLKSEL1 &= ~(3<<6); /* PCLK_UART0 = CCLK/4 (18MHz) */
//**LPC_SC->PCLKSEL1 |= (2<<6); /* PCLK_UART0 = CCLK/2 (36MHz) */
//**pclk = SystemCoreClock/2;
/* By default, the PCLKSELx value is zero, thus, the PCLK for
all the peripherals is 1/4 of the SystemFrequency. */
/* Bit 6~7 is for UART0 */
pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
switch ( pclkdiv )
{
case 0x00:
default:
pclk = SystemCoreClock/4;
break;
case 0x01:
pclk = SystemCoreClock;
break;
case 0x02:
pclk = SystemCoreClock/2;
break;
case 0x03:
pclk = SystemCoreClock/8;
break;
}
LPC_UART0->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */
LPC_UART0->DLM = Fdiv / 256;
LPC_UART0->DLL = Fdiv % 256;
LPC_UART0->LCR = 0x03; /* DLAB = 0 */
LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
}
/**
* @brief Write one character to UART0.
*
* @param ch: Character to be written
* @retval None
*/
void LPC17xx_UART_PutChar (uint8_t ch)
{
while (!(LPC_UART0->LSR & 0x20));
LPC_UART0->THR = ch;
}
/**
* @brief Read one character from UART0 (blocking read).
*
* @param None
* @retval Received character
*/
uint8_t LPC17xx_UART_GetChar (void)
{
while (!(LPC_UART0->LSR & 0x01));
return (LPC_UART0->RBR);
}
/**
* @brief Read one character from UART0 (non blocking read).
*
* @param None
* @retval Received character
*/
uint8_t LPC17xx_UART_GetChar_nb (void)
{
if (LPC_UART0->LSR & 0x01)
return (LPC_UART0->RBR);
else
return 0;
}
/**
* @brief Write a string to UART0.
*
* @param str: NULL-terminated char string to be written
* @retval None
*/
void LPC17xx_UART_PutString (uint8_t *str)
{
/* usage: LPC1700_UART_Printf("xxx\n\r");*/
#if 1
while (*str != 0)
{
LPC17xx_UART_PutChar(*str++);
}
#else
/* usage: LPC1700_UART_Printf("xxx\n");*/
while ((*str) != 0) {
if (*str == '\n') {
LPC17xx_UART_PutChar(*str++);
LPC17xx_UART_PutChar('\r');
} else {
LPC17xx_UART_PutChar(*str++);
}
}
#endif
}
/**
* @brief Print formatted string. This function takes variable length arguments.
*
* @param format
* @param ...
* @retval None
*
* Note: using library functions "vsprintf" will increase the RO size by about 6KB
*/
//void LPC17xx_UART_Printf (const uint8_t *format, ...)
//{
// static uint8_t buffer[40 + 1];
// va_list vArgs;
//
// va_start(vArgs, format);
// vsprintf((char *)buffer, (char const *)format, vArgs);
// va_end(vArgs);
// LPC17xx_UART_PutString((uint8_t *) buffer);
//}
/* --------------------------------- End Of File ------------------------------ */

View File

@@ -0,0 +1,37 @@
/**************************************************************************//**
* @file lpc17xx_uart.h
* @brief Header file for lpc17xx_uart.c.
* @version 1.0
* @date 18. Nov. 2010
*
* @note
* Copyright (C) 2010 NXP Semiconductors(NXP). All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
******************************************************************************/
#ifndef __LPC17xx_UART_H_
#define __LPC17xx_UART_H_
#include <stdint.h>
/* external functions */
void LPC17xx_UART_PutChar (uint8_t);
uint8_t LPC17xx_UART_GetChar (void);
void LPC17xx_UART_Init(uint32_t baudrate);
//void LPC17xx_UART_Printf (const uint8_t *format, ...);
void LPC17xx_UART_PutString (uint8_t *str) ;
#endif // __LPC17xx_UART_H_
/* --------------------------------- End Of File ------------------------------ */

116
platforms/lpc17xx/main.c Normal file
View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2012, Natie van Rooyen. All rights reserved.
*
* 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. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
*/
#include "LPC17xx.h"
#include "drivers/lpc17xx_uart.h"
#include <stdio.h>
#include "modules.h"
#include "atom.h"
#include "tests/atomtests.h"
// for mbed board
#define LED1_GPIO (1 << 18)
#define LED2_GPIO (1 << 20)
#define LED3_GPIO (1 << 21)
#define LED4_GPIO (1 << 23)
#define LED_GET(led) (LPC_GPIO1->FIOSET & led)
#define LED_SET(led, on) { if (on) LPC_GPIO1->FIOSET = led ; else LPC_GPIO1->FIOCLR = led ; }
#define LED_TOGGLE(led) LED_SET(led, !LED_GET(led))
#ifndef ATOMTHREADS_TEST
#define ATOMTHREADS_TEST "kern1"
#endif
#define TEST_STACK_BYTE_SIZE 1024
#define IDLE_STACK_BYTE_SIZE 512
static unsigned char test_stack[TEST_STACK_BYTE_SIZE] ;
static unsigned char idle_stack[IDLE_STACK_BYTE_SIZE] ;
ATOM_TCB test_tcb ;
/**
* \b test_thread
*
* Function calling the test function of the Atomthreads test suite.
*
*/
void
test_thread (uint32_t param)
{
uint32_t failures ;
static volatile unsigned int i ;
CRITICAL_STORE ;
failures = test_start () ;
atomTimerDelay (10) ;
CRITICAL_START() ;
dbg_format_msg ("%s %s\r\n", ATOMTHREADS_TEST, failures ? "FAIL" : "PASS") ;
CRITICAL_END() ;
while(1) {
LED_TOGGLE(LED1_GPIO) ;
for (i=0; i<1000000; i++) ;
}
}
int main(void) {
static volatile unsigned int i ;
// mbed board
LPC_GPIO1->FIODIR |= LED1_GPIO | LED2_GPIO | LED3_GPIO | LED4_GPIO ;
dbg_format_msg ("\r\nLPC17xx SystemCoreClock = %d\r\n",SystemCoreClock) ;
//atomthreads_stress_test (36) ;
dbg_format_msg ("Atomthreads starting %s... \r\n", ATOMTHREADS_TEST) ;
atomOSInit(&idle_stack[0], IDLE_STACK_BYTE_SIZE, TRUE) ;
atomThreadCreate ((ATOM_TCB *)&test_tcb, TEST_THREAD_PRIO, test_thread, 0, &test_stack[0], TEST_STACK_BYTE_SIZE, TRUE);
atomOSStart() ;
while(1) {
LED_TOGGLE(LED1_GPIO) ;
for (i=0; i<1000000; i++) ;
}
return 0 ;
}

178
platforms/lpc17xx/modules.c Normal file
View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2012, Natie van Rooyen. All rights reserved.
*
* 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. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
*/
#include "modules.h"
#include <stdio.h>
#include <stdarg.h>
#include "atomport_private.h"
#include "atom.h"
#include "atomport.h"
/**
* \b dbg_format_msg
*
* Same as printf.
*
*/
void
dbg_format_msg (char *format, ...)
{
va_list args;
static char msg[256] ;
//CRITICAL_STORE ;
va_start (args, format) ;
//CRITICAL_START() ;
vsnprintf ((char*)msg, 256, (char*)format, args) ;
LPC17xx_UART_PutString (msg) ;
//CRITICAL_END() ;
}
/**
* \b low_level_init
*
* Initializes the PIC and start the system timer tick intrerupt.
*
*/
int
low_level_init (void)
{
SystemInit () ;
SystemCoreClockUpdate ();
//contextInit () ;
NVIC_SetPriority (PendSV_IRQn, 0xFF) ;
LPC17xx_UART_Init (115200) ;
SysTick_Config (1000000) ;
return 0 ;
}
/**
* \b __context_preempt_handler
*
* System timer tic interupt handler.
*
*/
void
__context_tick_handler (void)
{
/* Call the interrupt enter routine */
atomIntEnter();
/* Call the OS system tick handler */
atomTimerTick();
/* Call the interrupt exit routine */
atomIntExit(TRUE);
}
/**
* \b dbg_mem_dump_40
*
* Dumps size bytes of memory from data.
*
*/
void dbg_mem_dump_40 (unsigned int* data, int size)
{
int j ;
dbg_format_msg ("Dump %d bytes at %.8X:\r\n",size * 4, (unsigned int)data) ;
data = (unsigned int*)((unsigned int)data & ~0x3) ;
for (j=0; j<size-3; j+=4) {
dbg_format_msg (" :%.8X: %.8X %.8X %.8X %.8X\r\n", (unsigned int)&data[j], data[j+0], data[j+1], data[j+2], data[j+3]) ;
}
if (size-j == 3) {
dbg_format_msg (" :%.8X: %.8X %.8X %.8X\r\n", (unsigned int)&data[j], data[j+0], data[j+1], data[j+2]) ;
} else if (size-j == 2) {
dbg_format_msg (" :%.8X: %.8X %.8X\r\n", (unsigned int)&data[j], data[j+0], data[j+1]) ;
} else if (size-j == 1) {
dbg_format_msg (" :%.8X: %.8X\r\n", (unsigned int)&data[j], data[j+0]) ;
}
}
/**
* \b dbg_fault_handler
*
* Prints cortex m exception debug information.
*
*/
void
dbg_fault_handler (unsigned int * hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
dbg_format_msg ("\r\n\r\n[Hard fault handler - all numbers in hex]\r\n");
dbg_format_msg ("SP = 0x%x\r\n", hardfault_args);
dbg_format_msg ("R0 = 0x%x\r\n", stacked_r0);
dbg_format_msg ("R1 = 0x%x\r\n", stacked_r1);
dbg_format_msg ("R2 = 0x%x\r\n", stacked_r2);
dbg_format_msg ("R3 = 0x%x\r\n", stacked_r3);
dbg_format_msg ("R12 = 0x%x\r\n", stacked_r12);
dbg_format_msg ("LR [R14] = 0x%x subroutine call return address\r\n", stacked_lr);
dbg_format_msg ("PC [R15] = 0x%x program counter\r\n", stacked_pc);
dbg_format_msg ("PSR = 0x%x\r\n", stacked_psr);
//printf ("BFAR = 0x%x\r\n", (*((volatile unsigned long *)(0xE000ED38))));
//printf ("CFSR = 0x%x\r\n", (*((volatile unsigned long *)(0xE000ED28))));
//printf ("HFSR = 0x%x\r\n", (*((volatile unsigned long *)(0xE000ED2C))));
//printf ("DFSR = 0x%x\r\n", (*((volatile unsigned long *)(0xE000ED30))));
//printf ("AFSR = 0x%x\r\n", (*((volatile unsigned long *)(0xE000ED3C))));
// printf ("SCB_SHCSR = %x\n", SCB->SHCSR);
dbg_mem_dump_40 (hardfault_args, 0x40) ;
while (1);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2012, Natie van Rooyen. All rights reserved.
*
* 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. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __MODULES_H__
#define __MODULES_H__
/*
* Module definitions to use with the Stellaris LM3S6965 Microcontroller
*/
#include "LPC17xx.h"
#include "drivers/lpc17xx_uart.h"
/* Function prototypes */
extern int low_level_init (void) ;
extern void dbg_format_msg (char *format, ...) ;
extern void dbg_fault_handler (unsigned int * hardfault_args) ;
#endif /* __MODULES_H__ */

295
platforms/lpc17xx/startup.c Normal file
View File

@@ -0,0 +1,295 @@
/**************************************************************************//**
* @file startup.c
* @brief
* @version
* @date
*
* @note
* Copyright (C) 2010 NXP Semiconductors(NXP). All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
******************************************************************************/
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
#include "system_LPC17xx.h"
#include "atomport_private.h"
void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void MemManage_Handler(void);
WEAK void BusFault_Handler(void);
WEAK void UsageFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void DebugMon_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefault_Handler(void);
//*****************************************************************************
//
// The entry point for the application.
// __main() is the entry point for Redlib based applications
// main() is the entry point for Newlib based applications
//
//*****************************************************************************
extern int main(void);
//*****************************************************************************
//
// External declaration for the pointer to the stack top from the Linker Script
//
//*****************************************************************************
extern void _vStackTop(void);
//*****************************************************************************
//
// The vector table.
// This relies on the linker script to place at correct location in memory.
//
//*****************************************************************************
extern void (* const g_pfnVectors[])(void);
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
// Core Level - CM3
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
archPendSVHandler, // The PendSV handler
archTickHandler /*SysTick_Handler*/, // The SysTick handler
// Chip Level - LPC17
IntDefault_Handler, // 16, 0x40 - WDT
IntDefault_Handler, // 17, 0x44 - TIMER0
IntDefault_Handler, // 18, 0x48 - TIMER1
IntDefault_Handler, // 19, 0x4c - TIMER2
IntDefault_Handler, // 20, 0x50 - TIMER3
IntDefault_Handler, // 21, 0x54 - UART0
IntDefault_Handler, // 22, 0x58 - UART1
IntDefault_Handler, // 23, 0x5c - UART2
IntDefault_Handler, // 24, 0x60 - UART3
IntDefault_Handler, // 25, 0x64 - PWM1
IntDefault_Handler, // 26, 0x68 - I2C0
IntDefault_Handler, // 27, 0x6c - I2C1
IntDefault_Handler, // 28, 0x70 - I2C2
IntDefault_Handler, // 29, 0x74 - SPI
IntDefault_Handler, // 30, 0x78 - SSP0
IntDefault_Handler, // 31, 0x7c - SSP1
IntDefault_Handler, // 32, 0x80 - PLL0 (Main PLL)
IntDefault_Handler, // 33, 0x84 - RTC
IntDefault_Handler, // 34, 0x88 - EINT0
IntDefault_Handler, // 35, 0x8c - EINT1
IntDefault_Handler, // 36, 0x90 - EINT2
IntDefault_Handler, // 37, 0x94 - EINT3
IntDefault_Handler, // 38, 0x98 - ADC
IntDefault_Handler, // 39, 0x9c - BOD
IntDefault_Handler, // 40, 0xA0 - USB
IntDefault_Handler, // 41, 0xa4 - CAN
IntDefault_Handler, // 42, 0xa8 - GP DMA
IntDefault_Handler, // 43, 0xac - I2S
IntDefault_Handler, // 44, 0xb0 - Ethernet
IntDefault_Handler, // 45, 0xb4 - RITINT
IntDefault_Handler, // 46, 0xb8 - Motor Control PWM
IntDefault_Handler, // 47, 0xbc - Quadrature Encoder
IntDefault_Handler, // 48, 0xc0 - PLL1 (USB PLL)
IntDefault_Handler, // 49, 0xc4 - USB Activity interrupt to wakeup
IntDefault_Handler, // 50, 0xc8 - CAN Activity interrupt to wakeup
};
//*****************************************************************************
// Functions to carry out the initialization of RW and BSS data sections. These
// are written as separate functions rather than being inlined within the
// ResetISR() function in order to cope with MCUs with multiple banks of
// memory.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int *pulSrc = (unsigned int*) romstart;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = *pulSrc++;
}
__attribute__ ((section(".after_vectors")))
void bss_init(unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = 0;
}
//*****************************************************************************
// The following symbols are constructs generated by the linker, indicating
// the location of various points in the "Global Section Table". This table is
// created by the linker via the Code Red managed linker script mechanism. It
// contains the load address, execution address and length of each RW data
// section and the execution and length of each BSS (zero initialized) section.
//*****************************************************************************
extern unsigned int __data_section_table;
extern unsigned int __data_section_table_end;
extern unsigned int __bss_section_table;
extern unsigned int __bss_section_table_end;
//*****************************************************************************
// Reset entry point for your code.
// Sets up a simple runtime environment and initializes the C/C++
// library.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void
ResetISR(void) {
//
// Copy the data sections from flash to SRAM.
//
unsigned int LoadAddr, ExeAddr, SectionLen;
unsigned int *SectionTableAddr;
// Load base address of Global Section Table
SectionTableAddr = &__data_section_table;
// Copy the data sections from flash to SRAM.
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
}
// At this point, SectionTableAddr = &__bss_section_table;
// Zero fill the bss segment
while (SectionTableAddr < &__bss_section_table_end) {
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
bss_init(ExeAddr, SectionLen);
}
low_level_init();
main();
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while (1) ;
}
//*****************************************************************************
// Default exception handlers. Override the ones here by defining your own
// handler routines in your application code.
//*****************************************************************************
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void NMI_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void HardFault_Handler(void)
{
__asm volatile
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" b dbg_fault_handler \n"
);
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void MemManage_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void BusFault_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void UsageFault_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void SVC_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void DebugMon_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void PendSV_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void SysTick_Handler(void)
{
while(1) ;
}
__attribute__ ((section(".after_vectors"))) __attribute__( ( naked ) )
void IntDefault_Handler(void)
{
while(1) ;
}

148
platforms/lpc17xx/system.ld Normal file
View File

@@ -0,0 +1,148 @@
/**************************************************************************//**
* @file system.ld
* @brief
* @version
* @date
*
* @note
* Copyright (C) 2010 NXP Semiconductors(NXP). All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
******************************************************************************/
MEMORY
{
/* Define each memory region */
MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512k */
RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */
}
/* Define a symbol for the top of each memory region */
__top_MFlash512 = 0x0 + 0x80000;
__top_RamLoc32 = 0x10000000 + 0x8000;
__top_RamAHB32 = 0x2007c000 + 0x8000;
ENTRY(ResetISR)
SECTIONS
{
/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
KEEP(*(.isr_vector))
/* Global Section Table */
. = ALIGN(4) ;
__section_table_start = .;
__data_section_table = .;
LONG(LOADADDR(.data));
LONG( ADDR(.data)) ;
LONG( SIZEOF(.data));
LONG(LOADADDR(.data_RAM2));
LONG( ADDR(.data_RAM2)) ;
LONG( SIZEOF(.data_RAM2));
__data_section_table_end = .;
__bss_section_table = .;
LONG( ADDR(.bss));
LONG( SIZEOF(.bss));
LONG( ADDR(.bss_RAM2));
LONG( SIZEOF(.bss_RAM2));
__bss_section_table_end = .;
__section_table_end = . ;
/* End of Global Section Table */
*(.after_vectors*)
*(.text*)
*(.rodata .rodata.*)
. = ALIGN(4);
} > MFlash512
/*
* for exception handling/unwind - some Newlib functions (in common
* with C++ and STDC++) use this.
* Use KEEP so not discarded with --gc-sections
*/
.ARM.extab : ALIGN(4)
{
KEEP(*(.ARM.extab* .gnu.linkonce.armextab.*))
} > MFlash512
__exidx_start = .;
.ARM.exidx : ALIGN(4)
{
KEEP(*(.ARM.exidx* .gnu.linkonce.armexidx.*))
} > MFlash512
__exidx_end = .;
_etext = .;
.data_RAM2 : ALIGN(4)
{
FILL(0xff)
*(.data.$RAM2*)
*(.data.$RamAHB32*)
. = ALIGN(4) ;
} > RamAHB32 AT>MFlash512
/* MAIN DATA SECTION */
.uninit_RESERVED : ALIGN(4)
{
KEEP(*(.bss.$RESERVED*))
. = ALIGN(4) ;
_end_uninit_RESERVED = .;
} > RamLoc32
.data : ALIGN(4)
{
FILL(0xff)
_data = .;
*(vtable)
*(.data*)
. = ALIGN(4) ;
_edata = .;
} > RamLoc32 AT>MFlash512
.bss_RAM2 : ALIGN(4)
{
*(.bss.$RAM2*)
*(.bss.$RamAHB32*)
. = ALIGN(4) ;
} > RamAHB32
/* MAIN BSS SECTION */
.bss : ALIGN(4)
{
__bss_start__ = . ;
_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4) ;
__bss_end__ = . ;
_ebss = .;
PROVIDE(end = .);
} > RamLoc32
PROVIDE(_pvHeapStart = .);
PROVIDE(_vStackTop = __top_RamLoc32 - 0);
}