[bsp] add new bsp for lpc824

This commit is contained in:
tanek liang 2017-07-28 21:34:18 +08:00
parent d4de2c53e3
commit db1cd8830a
84 changed files with 25045 additions and 0 deletions

View File

@ -0,0 +1,34 @@
# RT-Thread building script for component
Import('rtconfig')
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
src = Glob('peri_driver/*/*.c')
src += Glob('common/board/*.c')
src += Glob('common/chip/*.c')
# add for startup script
if rtconfig.CROSS_TOOL == 'gcc':
print "not gcc startup file"
exit(0)
elif rtconfig.CROSS_TOOL == 'keil':
src += [cwd + '/common/startup/keil_startup_lpc82x.s']
elif rtconfig.CROSS_TOOL == 'iar':
src += [cwd + '/common/startup/iar_startup_lpc82x.s']
CPPPATH = [ cwd + '/peri_driver', cwd + '/common/board',
cwd + '/common/chip', cwd + '/common/CMSIS']
if GetDepend(['RT_USING_BSP_CMSIS']):
CPPPATH += [cwd + '/common/CMSIS/']
elif GetDepend(['RT_USING_RTT_CMSIS']):
CPPPATH += [RTT_ROOT + '/components/CMSIS/Include']
CPPDEFINES = ['CORE_M0PLUS']
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES)
Return('group')

View File

@ -0,0 +1,734 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS Cortex-M Core Function/Instruction Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief Enable FIQ
\details 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
\details 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
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
/**
\brief Get FPSCR
\details 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 == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details 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 == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details 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
\details 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
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details 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() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details 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)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details 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
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details 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
\details 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 Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* (__CORTEX_M >= 0x04) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,914 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex-M0+
@{
*/
/* CMSIS CM0+ definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000U
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0U
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1U)
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1U)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1U)
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/**
\brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register Definitions */
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register Definitions */
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register Definitions */
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register Definitions */
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register Definitions */
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0+ header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1U)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,211 @@
/*
* @brief Common board API functions
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __BOARD_API_H_
#define __BOARD_API_H_
#include "lpc_types.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup BOARD_COMMON_API BOARD: Common board functions
* @ingroup BOARD_Common
* This file contains common board definitions that are shared across
* boards and devices. All of these functions do not need to be
* implemented for a specific board, but if they are implemented, they
* should use this API standard.
* @{
*/
/**
* @brief Setup and initialize hardware prior to call to main()
* @return None
* @note Board_SystemInit() is called prior to the application and sets up system
* clocking, memory, and any resources needed prior to the application
* starting.
*/
void Board_SystemInit(void);
/**
* @brief Setup pin multiplexer per board schematics
* @return None
* @note Board_SetupMuxing() should be called from SystemInit() prior to application
* main() is called. So that the PINs are set in proper state.
*/
void Board_SetupMuxing(void);
/**
* @brief Setup system clocking
* @return None
* @note This sets up board clocking.
*/
void Board_SetupClocking(void);
/**
* @brief Setup external system memory
* @return None
* @note This function is typically called after pin mux setup and clock setup and
* sets up any external memory needed by the system (DRAM, SRAM, etc.). Not all
* boards need this function.
*/
void Board_SetupExtMemory(void);
/**
* @brief Set up and initialize all required blocks and functions related to the board hardware.
* @return None
*/
void Board_Init(void);
/**
* @brief Initializes board UART for output, required for printf redirection
* @return None
*/
void Board_Debug_Init(void);
/**
* @brief Sends a single character on the UART, required for printf redirection
* @param ch : character to send
* @return None
*/
void Board_UARTPutChar(char ch);
/**
* @brief Sends a single character on the UART, automatic process '\n' -> '\r\n'
* @param ch : character to send
* @return None
*/
void Board_UARTPutTextChar(char ch);
/**
* @brief Classic implementation of itoa -- integer to ASCII
* @param value : value to convert
* @param result : result string
* @param base : output radix
* @return result string or NULL
*/
char *Board_itoa(int value, char *result, int base);
/**
* @brief Get a single character from the UART, required for scanf input
* @return EOF if not character was received, or character value
*/
int Board_UARTGetChar(void);
/**
* @brief Prints a string to the UART
* @param str : Terminated string to output
* @return None
*/
void Board_UARTPutSTR(const char *str);
/**
* @brief Get if a key is down
* @param keyIndex : The index of the key to detect
* @return 1 = key is down , 0 = key is up
*/
uint32_t Board_Key_GetKeyDown(uint32_t keyIndex);
/**
* @brief Sets the state of a board LED to on or off
* @param LEDNumber : LED number to set state for
* @param State : true for on, false for off
* @return None
*/
void Board_LED_Set(uint8_t LEDNumber, bool State);
/**
* @brief Returns the current state of a board LED
* @param LEDNumber : LED number to set state for
* @return true if the LED is on, otherwise false
*/
bool Board_LED_Test(uint8_t LEDNumber);
/**
* @brief Toggles the current state of a board LED
* @param LEDNumber : LED number to change state for
* @return None
*/
void Board_LED_Toggle(uint8_t LEDNumber);
/**
* @brief Turn on Board LCD Backlight
* @param Intensity : Backlight intensity (0 = off, >=1 = on)
* @return None
* @note On boards where a GPIO is used to control backlight on/off state, a '0' or '1'
* value will turn off or on the backlight. On some boards, a non-0 value will
* control backlight intensity via a PWN. For PWM systems, the intensity value
* is a percentage value between 0 and 100%.
*/
void Board_SetLCDBacklight(uint8_t Intensity);
/**
* @brief Function prototype for a MS delay function. Board layers or example code may
* define this function as needed.
*/
typedef void (*p_msDelay_func_t)(uint32_t);
/* The DEBUG* functions are selected based on system configuration.
Code that uses the DEBUG* functions will have their I/O routed to
the UART, semihosting, or nowhere. */
#if defined(DEBUG_ENABLE)
#if defined(DEBUG_SEMIHOSTING)
#define DEBUGINIT()
#define DEBUGOUT(...) printf(__VA_ARGS__)
#define DEBUGSTR(str) printf(str)
#define DEBUGIN() (int) EOF
#else
#define DEBUGINIT() Board_Debug_Init()
#define DEBUGOUT(...) printf(__VA_ARGS__)
#define DEBUGSTR(str) Board_UARTPutSTR(str)
#define DEBUGIN() Board_UARTGetChar()
#endif /* defined(DEBUG_SEMIHOSTING) */
#else
#define DEBUGINIT()
#define DEBUGOUT(...)
#define DEBUGSTR(str)
#define DEBUGIN() (int) EOF
#endif /* defined(DEBUG_ENABLE) */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_API_H_ */

View File

@ -0,0 +1,284 @@
/*
* @brief NXP LPCXpresso LPC824 board file
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
// Must define _BOARD_C_ before ANY include
#define _BOARD_C_
#include "board_lpc.h"
#include "string.h"
#include <stdint.h>
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#define BOARD_LED_CNT 8
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/* System oscillator rate and clock rate on the CLKIN pin */
const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ;
const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ;
/*****************************************************************************
* Private functions
****************************************************************************/
static void Board_Key_Init(void)
{
int i;
LPC_IOCON_T *pIOCON = LPC_IOCON;
for (i = 0; i < BOARD_KEY_CNT; i++) {
Chip_GPIO_PinSetDIR(LPC_GPIO_PORT, 0, cs_keyBits[i], 0);
pIOCON->PIO0[cs_keyIoConNdce[i]] = 0x80; // weak pUp
}
}
/* Initialize the LEDs on the NXP LPC824 LPCXpresso Board */
static void Board_LED_Init(void)
{
int i;
for (i = 0; i < BOARD_LED_CNT; i++) {
Chip_GPIO_PinSetDIR(LPC_GPIO_PORT, 0, ledBits[i], 1);
Chip_GPIO_PinSetState(LPC_GPIO_PORT, 0, ledBits[i], true);
}
}
uint32_t Board_Key_GetKeyDown(uint32_t keyNdx)
{
LPC_GPIO_T *pGP = LPC_GPIO_PORT;
return pGP->W[0][cs_keyBits[keyNdx]] == 0 ? 1 : 0;
}
/* Board Debug UART Initialisation function */
STATIC void Board_UART_Init(void)
{
/* Enable the clock to the Switch Matrix */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
/* Connect the TXD_O and RXD_I signals to port pins(P0.4, P0.0) */
//Chip_SWM_DisableFixedPin(SWM_FIXED_XTALIN);
//Chip_SWM_DisableFixedPin(SWM_FIXED_XTALOUT);
Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I1);
Chip_SWM_DisableFixedPin(SWM_FIXED_ADC11);
/* Enable UART Divider clock, divided by 1 */
Chip_Clock_SetUARTClockDiv(1);
/* Divided by 1 */
if (DEBUG_UART == LPC_USART0) {
Chip_SWM_MovablePinAssign(SWM_U0_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U0_RXD_I, 0);
} else if (DEBUG_UART == LPC_USART1) {
Chip_SWM_MovablePinAssign(SWM_U1_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U1_RXD_I, 0);
} else {
Chip_SWM_MovablePinAssign(SWM_U2_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U2_RXD_I, 0);
}
/* Disable the clock to the Switch Matrix to save power */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
}
/* Initializes pin muxing for SPI1 interface - note that SystemInit() may
already setup your pin muxing at system startup */
static void Init_SPI_PinMux(void)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_MovablePinAssign(SWM_SPI1_SSEL0_IO, 15);
Chip_SWM_MovablePinAssign(SWM_SPI1_SCK_IO, 24);
Chip_SWM_MovablePinAssign(SWM_SPI1_MISO_IO, 25);
Chip_SWM_MovablePinAssign(SWM_SPI1_MOSI_IO, 26);
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
}
/* Initializes pin muxing for I2C interface */
static void Init_I2C_PinMux(void)
{
/* Enable the clock to the Switch Matrix */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_EnableFixedPin(SWM_FIXED_I2C0_SDA);
Chip_SWM_EnableFixedPin(SWM_FIXED_I2C0_SCL);
/* Enable Fast Mode Plus for I2C pins */
Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO10, PIN_I2CMODE_FASTPLUS);
Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO11, PIN_I2CMODE_FASTPLUS);
/* Disable the clock to the Switch Matrix to save power */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Set the LED to the state of "On" */
void Board_LED_Set(uint8_t LEDNumber, bool On)
{
if (LEDNumber < BOARD_LED_CNT) {
Chip_GPIO_PinSetState(LPC_GPIO_PORT, 0, ledBits[LEDNumber], (bool) !On);
}
}
/* Return the state of LEDNumber */
bool Board_LED_Test(uint8_t LEDNumber)
{
bool state = false;
if (LEDNumber < BOARD_LED_CNT) {
state = (bool) !Chip_GPIO_PinGetState(LPC_GPIO_PORT, 0, ledBits[LEDNumber]);
}
return state;
}
/* Toggles the current state of a board LED */
void Board_LED_Toggle(uint8_t LEDNumber)
{
if (LEDNumber < BOARD_LED_CNT) {
Chip_GPIO_PinToggleState(LPC_GPIO_PORT, 0, ledBits[LEDNumber]);
}
}
/* Classic implementation of itoa -- integer to ASCII */
char *Board_itoa(int value, char *result, int base)
{
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
if (base < 2 || base > 36) { *result = '\0'; return result; }
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
/* Sends a character on the UART */
void Board_UARTPutChar(char ch)
{
#if defined(DEBUG_UART)
Chip_UART_SendBlocking(DEBUG_UART, &ch, 1);
#endif
}
void Board_UARTPutTextChar(char ch)
{
#if defined(DEBUG_UART)
static char prevChar = 0;
if (ch == '\n' && prevChar != '\r')
{
prevChar = '\r';
Chip_UART_SendBlocking(DEBUG_UART, &prevChar, 1);
Chip_UART_SendBlocking(DEBUG_UART, &ch, 1);
} else {
Chip_UART_SendBlocking(DEBUG_UART, &ch, 1);
prevChar = ch;
}
#endif
}
/* Gets a character from the UART, returns EOF if no character is ready */
int Board_UARTGetChar(void)
{
#if defined(DEBUG_UART)
uint8_t data;
if (Chip_UART_ReadBlocking(DEBUG_UART, &data, 1) == 1) {
Board_UARTPutChar(data); // echo back the char
return (int) data;
}
#endif
return EOF;
}
/* Outputs a string on the debug UART */
void Board_UARTPutSTR(const char *str)
{
#if defined(DEBUG_UART)
while (*str != '\0') {
Board_UARTPutTextChar(*str++);
}
#endif
}
/* Initialize debug output via UART for board */
void Board_Debug_Init(void)
{
#if defined(DEBUG_UART)
Board_UART_Init();
Chip_UART_Init(DEBUG_UART);
Chip_UART_ConfigData(DEBUG_UART, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1);
Chip_Clock_SetUSARTNBaseClockRate((115200 * 6 * 16), true);
Chip_UART_SetBaud(DEBUG_UART, 115200);
Chip_UART_Enable(DEBUG_UART);
Chip_UART_TXEnable(DEBUG_UART);
#endif
}
/* Set up and initialize all required blocks and functions related to the
board hardware */
void Board_Init(void)
{
LPC_SWM_T *pSWM = LPC_SWM;
/* Sets up DEBUG UART */
#if defined(DEBUG_ENABLE)
DEBUGINIT();
//pSWM->PINENABLE0 |= ~(1UL<<SWM_FIXED_SWCLK | 1UL<<SWM_FIXED_SWDIO | 1UL<<SWM_FIXED_RST);
#ifdef USE_IRC_AS_ROOT_CLOCK
pSWM->PINENABLE0 |= 1UL<<SWM_FIXED_XTALIN | 1UL<<SWM_FIXED_XTALOUT;
#endif
#endif
/* Initialize GPIO */
Chip_GPIO_Init(LPC_GPIO_PORT);
/* Initialize the LEDs */
Board_LED_Init();
//Board_Key_Init();
Init_SPI_PinMux();
Init_I2C_PinMux();
}

View File

@ -0,0 +1,117 @@
/*
* @brief NXP LPCXpresso LPC824 board file
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __BOARD_H_
#define __BOARD_H_
#include "chip.h"
/* board_api.h is included at the bottom of this file after DEBUG setup */
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup BOARD_NXP_LPCXPRESSO_824 NXP LPC824 LPCXpresso board support software API functions
* @ingroup LPCOPEN_8XX_BOARD_LPCXPRESSO_824
* The board support software API functions provide some simple abstracted
* functions used across multiple LPCOpen board examples. See @ref BOARD_COMMON_API
* for the functions defined by this board support layer.<br>
* @{
*/
/** @defgroup LPCOPEN_8XX_BOARD_LPCXPRESSO_824_OPTIONS BOARD: LPC824 LPCXpresso board build options
* This board has options that configure its operation at build-time.<br>
* @{
*/
/** Define the frequency in Hz, of the main oscillator (from Xtal)
* Note that it only takes effect if main oscillator is selected as clock source
*/
#define MAIN_OSC_XTAL_FREQ_HZ 12000000
/** Define the frequency in Hz, of the external clock input.
* Note that it only takes effect if external clock is selected as clock source
*/
#define EXT_CLOCK_IN_FREQ_HZ 0
//#define USE_IRC_AS_ROOT_CLOCK /*注释掉使用外部晶体 打开定义则是使用内部IRC*/
#define BOARD_LED_CNT 8
#define BOARD_KEY_CNT 3
typedef enum _enum_boardKeys
{
BOARD_KEY_0 = 0,
BOARD_KEY_1 = 1,
BOARD_KEY_2 = 2,
}enum_boardKeys;
// define LED bits (bit <--> pin on port 0) only if in board.c file
#ifdef _BOARD_C_
static const uint8_t ledBits[BOARD_LED_CNT] = {7, 13, 16, 17, 19, 27, 28, 18};
static const uint8_t cs_keyBits[BOARD_KEY_CNT] = {12, 4 , 1};
static const uint8_t cs_keyIoConNdce[BOARD_KEY_CNT] = {IOCON_PIO12, IOCON_PIO4, IOCON_PIO1};
#endif
/** Define DEBUG_ENABLE to enable IO via the DEBUGSTR, DEBUGOUT, and
DEBUGIN macros. If not defined, DEBUG* functions will be optimized
out of the code at build time.
*/
#define DEBUG_ENABLE
/** Define DEBUG_SEMIHOSTING along with DEBUG_ENABLE to enable IO support
via semihosting. You may need to use a C library that supports
semihosting with this option.
*/
//#define DEBUG_SEMIHOSTING
/** Board UART used for debug output and input using the DEBUG* macros. This
is also the port used for Board_UARTPutChar, Board_UARTGetChar, and
Board_UARTPutSTR functions. Although you can setup multiple UARTs here,
the board code only supoprts UART0 in the Board_UART_Init() fucntion,
so be sure to change it there too if not using UART0.
*/
#define DEBUG_UART LPC_USART1
/**
* @}
*/
/* Board name */
#define BOARD_NXP_LPCXPRESSO_824
#include "board_api.h"
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H_ */

View File

@ -0,0 +1,230 @@
/*
* @brief LPC8xx basic chip inclusion file
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __CHIP_H_
#define __CHIP_H_
#include "lpc_types.h"
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CORE_M0PLUS
#error CORE_M0PLUS is not defined for the LPC8xx architecture
#error CORE_M0PLUS should be defined as part of your compiler define list
#endif
#ifndef CHIP_LPC8XX
#error The LPC8XX Chip include path is used for this build, but
#error CHIP_LPC8XX is not defined!
#endif
/** @defgroup PERIPH_8XX_BASE CHIP: LPC8xx Peripheral addresses and register set declarations
* @ingroup CHIP_8XX_Drivers
* @{
*/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_ROM_BASE (0x1FFF0000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_WWDT_BASE (0x40000000UL)
#define LPC_MRT_BASE (0x40004000UL)
#define LPC_WKT_BASE (0x40008000UL)
#define LPC_SWM_BASE (0x4000C000UL)
#define LPC_ADC_BASE (0x4001C000UL) /* Available only on LPC82x */
#define LPC_PMU_BASE (0x40020000UL)
#define LPC_CMP_BASE (0x40024000UL)
#define LPC_DMATIRGMUX_BASE (0x40028000UL) /* Available only on LPC82x */
#define LPC_INMUX_BASE (0x4002C000UL) /* Available only on LPC82x */
#define LPC_FMC_BASE (0x40040000UL)
#define LPC_IOCON_BASE (0x40044000UL)
#define LPC_SYSCTL_BASE (0x40048000UL)
#define LPC_I2C0_BASE (0x40050000UL)
#define LPC_I2C1_BASE (0x40054000UL) /* Available only on LPC82x */
#define LPC_SPI0_BASE (0x40058000UL)
#define LPC_SPI1_BASE (0x4005C000UL)
#define LPC_USART0_BASE (0x40064000UL)
#define LPC_USART1_BASE (0x40068000UL)
#define LPC_USART2_BASE (0x4006C000UL)
#define LPC_I2C2_BASE (0x40070000UL) /* Available only on LPC82x */
#define LPC_I2C3_BASE (0x40074000UL) /* Available only on LPC82x */
/* AHB peripherals */
#define LPC_CRC_BASE (0x50000000UL)
#define LPC_SCT_BASE (0x50004000UL)
#define LPC_DMA_BASE (0x50008000UL) /* Available only on LPC82x */
#define LPC_GPIO_PORT_BASE (0xA0000000UL)
#define LPC_PIN_INT_BASE (0xA0004000UL)
#define LPC_WWDT ((LPC_WWDT_T *) LPC_WWDT_BASE)
#define LPC_SPI0 ((LPC_SPI_T *) LPC_SPI0_BASE)
#define LPC_SPI1 ((LPC_SPI_T *) LPC_SPI1_BASE)
#define LPC_USART0 ((LPC_USART_T *) LPC_USART0_BASE)
#define LPC_USART1 ((LPC_USART_T *) LPC_USART1_BASE)
#define LPC_USART2 ((LPC_USART_T *) LPC_USART2_BASE)
#define LPC_WKT ((LPC_WKT_T *) LPC_WKT_BASE)
#define LPC_PMU ((LPC_PMU_T *) LPC_PMU_BASE)
#define LPC_CRC ((LPC_CRC_T *) LPC_CRC_BASE)
#define LPC_SCT ((LPC_SCT_T *) LPC_SCT_BASE)
#define LPC_GPIO_PORT ((LPC_GPIO_T *) LPC_GPIO_PORT_BASE)
#define LPC_PININT ((LPC_PININT_T *) LPC_PIN_INT_BASE)
#define LPC_IOCON ((LPC_IOCON_T *) LPC_IOCON_BASE)
#define LPC_SWM ((LPC_SWM_T *) LPC_SWM_BASE)
#define LPC_SYSCTL ((LPC_SYSCTL_T *) LPC_SYSCTL_BASE)
#define LPC_CMP ((LPC_CMP_T *) LPC_CMP_BASE)
#define LPC_FMC ((LPC_FMC_T *) LPC_FMC_BASE)
#define LPC_MRT ((LPC_MRT_T *) LPC_MRT_BASE)
#define LPC_I2C0 ((LPC_I2C_T *) LPC_I2C0_BASE)
#ifdef CHIP_LPC82X
/* Peripherals available only on LPC82x */
#define LPC_ADC ((LPC_ADC_T *) LPC_ADC_BASE)
#define LPC_I2C1 ((LPC_I2C_T *) LPC_I2C1_BASE)
#define LPC_I2C2 ((LPC_I2C_T *) LPC_I2C2_BASE)
#define LPC_I2C3 ((LPC_I2C_T *) LPC_I2C3_BASE)
#define LPC_DMA ((LPC_DMA_T *) LPC_DMA_BASE)
#define LPC_DMATRIGMUX ((LPC_DMATRIGMUX_T *) LPC_DMATIRGMUX_BASE)
#define LPC_INMUX ((LPC_INMUX_T *) LPC_INMUX_BASE)
#endif
/* Base address Alias list */
#define LPC_I2C_BASE LPC_I2C0_BASE
#define LPC_I2C LPC_I2C0
#define LPC_SYSCON LPC_SYSCTL
/* IRQ Handler alias list */
#ifdef CHIP_LPC82X
#define I2C_IRQHandler I2C0_IRQHandler
#define PININT0_IRQHandler PIN_INT0_IRQHandler
#define PININT1_IRQHandler PIN_INT1_IRQHandler
#define PININT2_IRQHandler PIN_INT2_IRQHandler
#define PININT3_IRQHandler PIN_INT3_IRQHandler
#define PININT4_IRQHandler PIN_INT4_IRQHandler
#define PININT5_IRQHandler PIN_INT5_IRQHandler
#define PININT6_IRQHandler PIN_INT6_IRQHandler
#define PININT7_IRQHandler PIN_INT7_IRQHandler
#endif
/**
* @}
*/
/** @ingroup CHIP_8XX_DRIVER_OPTIONS
* @{
*/
/**
* @brief System oscillator rate
* This value is defined externally to the chip layer and contains
* the value in Hz for the external oscillator for the board. If using the
* internal oscillator, this rate can be 0.
*/
extern const uint32_t OscRateIn;
/**
* @brief Clock rate on the CLKIN pin
* This value is defined externally to the chip layer and contains
* the value in Hz for the CLKIN pin for the board. If this pin isn't used,
* this rate can be 0.
*/
extern const uint32_t ExtRateIn;
/**
* @}
*/
/* Include order is important! */
#include "syscon_8xx.h"
#include "clock_8xx.h"
#include "fmc_8xx.h"
#include "ioswm_8xx.h"
#ifndef _CHIP_COMMON_
#include "../../peri_driver/peri_driver.h"
#endif
/** @defgroup SUPPORT_8XX_FUNC CHIP: LPC8xx support functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Current system clock rate, mainly used for sysTick
*/
extern uint32_t SystemCoreClock;
/**
* @brief Update system core clock rate, should be called if the
* system has a clock rate change
* @return None
*/
void SystemCoreClockUpdate(void);
/**
* @brief Set up and initialize hardware prior to call to main()
* @return None
* @note Chip_SystemInit() is called prior to the application and sets up
* system clocking prior to the application starting.
*/
void Chip_SystemInit(void);
/**
* @brief Clock and PLL initialization based on the external oscillator
* @return None
* @note This function assumes an external crystal oscillator
* frequency of 12MHz.
*/
void Chip_SetupXtalClocking(void);
/**
* @brief Clock and PLL initialization based on the internal oscillator
* @return None
*/
void Chip_SetupIrcClocking(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CHIP_H_ */

View File

@ -0,0 +1,468 @@
/*
* @brief LPC8xx clock driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#define _CHIP_COMMON_
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Inprecise clock rates for the watchdog oscillator */
static const uint32_t wdtOSCRate[WDTLFO_OSC_4_60 + 1] = {
0, /* WDT_OSC_ILLEGAL */
600000, /* WDT_OSC_0_60 */
1050000, /* WDT_OSC_1_05 */
1400000, /* WDT_OSC_1_40 */
1750000, /* WDT_OSC_1_75 */
2100000, /* WDT_OSC_2_10 */
2400000, /* WDT_OSC_2_40 */
2700000, /* WDT_OSC_2_70 */
3000000, /* WDT_OSC_3_00 */
3250000, /* WDT_OSC_3_25 */
3500000, /* WDT_OSC_3_50 */
3750000, /* WDT_OSC_3_75 */
4000000, /* WDT_OSC_4_00 */
4200000, /* WDT_OSC_4_20 */
4400000, /* WDT_OSC_4_40 */
4600000 /* WDT_OSC_4_60 */
};
typedef struct {
uint16_t freq_main; // main clock frequency in MHz
uint16_t freq_sys; // system (CPU) clock frequency in MHz
uint16_t freq_fcco; // FCCO clock frequency in MHz
uint16_t msel; // MSEL (pre-decremented)
uint16_t psel; // PSEL (pre-decremented)
uint16_t divider; // SYSAHBCLKDIV
} LPC_8XX_PLL_T;
/*
* This table contains all useful PLL configurations
* for "integer" MHZ (e.g. 1MHz, 2MHz, etc.) frequencies.
*
* This table has two inputs:
* - freq_main: This is the main frequency.
* - freq_sys: This is the system (CPU) frequency.
* These are used to select which table entry to use.
*
* There are many ways to get some frequencies. For example,
* there are eight ways to make the CPU run at 12MHZ. If the peripheral bus
* needs to run very fast, it's possible to set the main clock
* up to 96MHz. If low power is a requirement, it's possible to set the main
* clock to 12MHz.
*
* All the rest of the table entries are outputs.
* - freq_fcco is simply an FYI value. It is not used for programming.
* - MSEL / PSEL / divider are used to program the PLL.
*/
static const LPC_8XX_PLL_T config_tab[] = {
{ 12, 12, 192, 0, 3, 1 }, // 12.0000MHz
{ 12, 6, 192, 0, 3, 2 }, // 6.0000MHz
{ 12, 4, 192, 0, 3, 3 }, // 4.0000MHz
{ 12, 3, 192, 0, 3, 4 }, // 3.0000MHz
{ 12, 2, 192, 0, 3, 6 }, // 2.0000MHz
{ 12, 1, 192, 0, 3, 12 }, // 1.0000MHz
{ 24, 24, 192, 1, 2, 1 }, // 24.0000MHz
{ 24, 12, 192, 1, 2, 2 }, // 12.0000MHz
{ 24, 8, 192, 1, 2, 3 }, // 8.0000MHz
{ 24, 6, 192, 1, 2, 4 }, // 6.0000MHz
{ 24, 4, 192, 1, 2, 6 }, // 4.0000MHz
{ 24, 3, 192, 1, 2, 8 }, // 3.0000MHz
{ 24, 2, 192, 1, 2, 12 }, // 2.0000MHz
{ 24, 1, 192, 1, 2, 24 }, // 1.0000MHz
{ 36, 18, 288, 2, 2, 2 }, // 18.0000MHz
{ 36, 12, 288, 2, 2, 3 }, // 12.0000MHz
{ 36, 9, 288, 2, 2, 4 }, // 9.0000MHz
{ 36, 6, 288, 2, 2, 6 }, // 6.0000MHz
{ 36, 4, 288, 2, 2, 9 }, // 4.0000MHz
{ 36, 3, 288, 2, 2, 12 }, // 3.0000MHz
{ 36, 2, 288, 2, 2, 18 }, // 2.0000MHz
{ 36, 1, 288, 2, 2, 36 }, // 1.0000MHz
{ 48, 24, 192, 3, 1, 2 }, // 24.0000MHz
{ 48, 16, 192, 3, 1, 3 }, // 16.0000MHz
{ 48, 12, 192, 3, 1, 4 }, // 12.0000MHz
{ 48, 8, 192, 3, 1, 6 }, // 8.0000MHz
{ 48, 6, 192, 3, 1, 8 }, // 6.0000MHz
{ 48, 4, 192, 3, 1, 12 }, // 4.0000MHz
{ 48, 3, 192, 3, 1, 16 }, // 3.0000MHz
{ 48, 2, 192, 3, 1, 24 }, // 2.0000MHz
{ 48, 1, 192, 3, 1, 48 }, // 1.0000MHz
{ 60, 30, 240, 4, 1, 2 }, // 30.0000MHz
{ 60, 20, 240, 4, 1, 3 }, // 20.0000MHz
{ 60, 15, 240, 4, 1, 4 }, // 15.0000MHz
{ 60, 12, 240, 4, 1, 5 }, // 12.0000MHz
{ 60, 10, 240, 4, 1, 6 }, // 10.0000MHz
{ 60, 6, 240, 4, 1, 10 }, // 6.0000MHz
{ 60, 5, 240, 4, 1, 12 }, // 5.0000MHz
{ 60, 4, 240, 4, 1, 15 }, // 4.0000MHz
{ 60, 3, 240, 4, 1, 20 }, // 3.0000MHz
{ 60, 2, 240, 4, 1, 30 }, // 2.0000MHz
{ 60, 1, 240, 4, 1, 60 }, // 1.0000MHz
{ 72, 24, 288, 5, 1, 3 }, // 24.0000MHz
{ 72, 18, 288, 5, 1, 4 }, // 18.0000MHz
{ 72, 12, 288, 5, 1, 6 }, // 12.0000MHz
{ 72, 9, 288, 5, 1, 8 }, // 9.0000MHz
{ 72, 8, 288, 5, 1, 9 }, // 8.0000MHz
{ 72, 6, 288, 5, 1, 12 }, // 6.0000MHz
{ 72, 4, 288, 5, 1, 18 }, // 4.0000MHz
{ 72, 3, 288, 5, 1, 24 }, // 3.0000MHz
{ 72, 2, 288, 5, 1, 36 }, // 2.0000MHz
{ 72, 1, 288, 5, 1, 72 }, // 1.0000MHz
{ 84, 28, 168, 6, 0, 3 }, // 28.0000MHz
{ 84, 21, 168, 6, 0, 4 }, // 21.0000MHz
{ 84, 14, 168, 6, 0, 6 }, // 14.0000MHz
{ 84, 12, 168, 6, 0, 7 }, // 12.0000MHz
{ 84, 7, 168, 6, 0, 12 }, // 7.0000MHz
{ 84, 6, 168, 6, 0, 14 }, // 6.0000MHz
{ 84, 4, 168, 6, 0, 21 }, // 4.0000MHz
{ 84, 3, 168, 6, 0, 28 }, // 3.0000MHz
{ 84, 2, 168, 6, 0, 42 }, // 2.0000MHz
{ 84, 1, 168, 6, 0, 84 }, // 1.0000MHz
{ 96, 24, 192, 7, 0, 4 }, // 24.0000MHz
{ 96, 16, 192, 7, 0, 6 }, // 16.0000MHz
{ 96, 12, 192, 7, 0, 8 }, // 12.0000MHz
{ 96, 8, 192, 7, 0, 12 }, // 8.0000MHz
{ 96, 6, 192, 7, 0, 16 }, // 6.0000MHz
{ 96, 4, 192, 7, 0, 24 }, // 4.0000MHz
{ 96, 3, 192, 7, 0, 32 }, // 3.0000MHz
{ 96, 2, 192, 7, 0, 48 }, // 2.0000MHz
{ 96, 1, 192, 7, 0, 96 }, // 1.0000MHz
};
static const uint16_t config_tab_ct = sizeof(config_tab) / sizeof(LPC_8XX_PLL_T);
static uint16_t config_tab_idx = 0;
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/* System Clock Frequency (Core Clock) */
uint32_t SystemCoreClock;
/*****************************************************************************
* Private functions
****************************************************************************/
static void pll_config(const LPC_8XX_PLL_T* pll_cfg)
{
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_IRC_PD); /* turn on the IRC by clearing the power down bit */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC); /* select PLL input to be IRC */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_IRC);
Chip_FMC_SetFLASHAccess(FLASHTIM_30MHZ_CPU); /* setup FLASH access to 2 clocks (up to 30MHz) */
Chip_SYSCTL_PowerDown(SYSCTL_SLPWAKE_SYSPLL_PD); /* power down PLL to change the PLL divider ratio */
Chip_Clock_SetupSystemPLL(pll_cfg->msel, pll_cfg->psel); /* configure the PLL */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_SYSPLL_PD); /* turn on the PLL by clearing the power down bit */
while (!Chip_Clock_IsSystemPLLLocked()) {} /* wait for PLL to lock */
Chip_Clock_SetSysClockDiv(pll_cfg->divider); /* load the divider */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT); /* enable the new Frequency */
}
/* Compute a WDT or LFO rate */
static uint32_t Chip_Clock_GetWDTLFORate(uint32_t reg)
{
uint32_t div;
CHIP_WDTLFO_OSC_T clk;
/* Get WDT oscillator settings */
clk = (CHIP_WDTLFO_OSC_T) ((reg >> 5) & 0xF);
div = reg & 0x1F;
/* Compute clock rate and divided by divde value */
return wdtOSCRate[clk] / ((div + 1) << 1);
}
/* Compute PLL frequency */
static uint32_t Chip_Clock_GetPLLFreq(uint32_t PLLReg, uint32_t inputRate)
{
uint32_t m_val = ((PLLReg & 0x1F) + 1);
return (inputRate * m_val);
}
/*****************************************************************************
* Public functions
****************************************************************************/
bool Chip_IRC_SetFreq(uint32_t main, uint32_t sys)
{
uint16_t freq_m = main/1000000; /* main frequency in MHz */
uint16_t freq_s = sys/1000000; /* system frequency in MHz */
bool found = false; /* frequencies found */
uint32_t i = 0;
if (freq_s > 30) /* if system frequency is higher than 30MHz... */
return false; /* ...don't attempt to set it */
if (freq_m > 96) /* if main frequency is higher than 96MHz... */
return false; /* ...don't attempt to set it */
for (i=0; i<config_tab_ct; i++) { /* loop through table */
if ((freq_m == config_tab[i].freq_main) && (freq_s == config_tab[i].freq_sys)) { /* attempt to find a match */
config_tab_idx = i; /* save the data for later */
found = true; /* set state to found */
break; /* go config the PLL */
}
}
if (found == true) { /* if a match has been found */
pll_config(&config_tab[config_tab_idx]); /* configure the PLL */
}
return found; /* return operation status */
}
// Open this API only if ROM headers are included
#ifdef LPC_PWRD_API
void Chip_IRC_SetFreq_ROM(uint32_t sys)
{
uint32_t cmd[4], resp[2];
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_IRC_PD); /* Turn on the IRC by clearing the power down bit */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC); /* Select PLL input to be IRC */
Chip_FMC_SetFLASHAccess(FLASHTIM_30MHZ_CPU); /* Setup FLASH access to 2 clocks (up to 30MHz) */
cmd[0] = Chip_Clock_GetIntOscRate() / 1000; /* in KHz */
cmd[1] = sys / 1000; /* system clock rate in kHz */
cmd[2] = CPU_FREQ_EQU;
cmd[3] = sys / 10000; /* Timeout. See UM10601, section 23.4.1.3 for details */
LPC_PWRD_API->set_pll(cmd, resp); /* Attempt to set the PLL */
while (resp[0] != PLL_CMD_SUCCESS) {} /* Dead loop on fail */
}
#else
#endif
/* Update system core clock rate, should be called if the system has
a clock rate change */
void SystemCoreClockUpdate(void)
{
/* CPU core speed */
SystemCoreClock = Chip_Clock_GetSystemClockRate();
}
/* Set System PLL clock source */
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
{
LPC_SYSCTL->SYSPLLCLKSEL = (uint32_t) src;
/* sequnce a 0 followed by 1 to update PLL source selection */
LPC_SYSCTL->SYSPLLCLKUEN = 0;
LPC_SYSCTL->SYSPLLCLKUEN = 1;
}
/* Bypass System Oscillator and set oscillator frequency range */
void Chip_Clock_SetPLLBypass(bool bypass, bool highfr)
{
uint32_t ctrl = 0;
if (bypass) {
ctrl |= (1 << 0);
}
if (highfr) {
ctrl |= (1 << 1);
}
LPC_SYSCTL->SYSOSCCTRL = ctrl;
}
/* Set main system clock source */
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src)
{
LPC_SYSCTL->MAINCLKSEL = (uint32_t) src;
/* sequnce a 0 followed by 1 to update MAINCLK source selection */
LPC_SYSCTL->MAINCLKUEN = 0;
LPC_SYSCTL->MAINCLKUEN = 1;
}
/* Set CLKOUT clock source and divider */
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div)
{
LPC_SYSCTL->CLKOUTSEL = (uint32_t) src;
/* sequnce a 0 followed by 1 to update CLKOUT source selection */
LPC_SYSCTL->CLKOUTUEN = 0;
LPC_SYSCTL->CLKOUTUEN = 1;
LPC_SYSCTL->CLKOUTDIV = div;
}
/* Return estimated watchdog oscillator rate */
uint32_t Chip_Clock_GetWDTOSCRate(void)
{
return Chip_Clock_GetWDTLFORate(LPC_SYSCTL->WDTOSCCTRL & ~SYSCTL_WDTOSCCTRL_RESERVED);
}
/* Return System PLL input clock rate */
uint32_t Chip_Clock_GetSystemPLLInClockRate(void)
{
uint32_t clkRate;
switch ((CHIP_SYSCTL_PLLCLKSRC_T) (LPC_SYSCTL->SYSPLLCLKSEL & 0x3)) {
case SYSCTL_PLLCLKSRC_IRC:
clkRate = Chip_Clock_GetIntOscRate();
break;
case SYSCTL_PLLCLKSRC_SYSOSC:
clkRate = Chip_Clock_GetMainOscRate();
break;
case SYSCTL_PLLCLKSRC_EXT_CLKIN:
clkRate = Chip_Clock_GetExtClockInRate();
break;
default:
clkRate = 0;
}
return clkRate;
}
/* Return System PLL output clock rate */
uint32_t Chip_Clock_GetSystemPLLOutClockRate(void)
{
return Chip_Clock_GetPLLFreq((LPC_SYSCTL->SYSPLLCTRL & ~SYSCTL_SYSPLLCTRL_RESERVED),
Chip_Clock_GetSystemPLLInClockRate());
}
/* Return main clock rate */
uint32_t Chip_Clock_GetMainClockRate(void)
{
uint32_t clkRate = 0;
switch ((CHIP_SYSCTL_MAINCLKSRC_T) (LPC_SYSCTL->MAINCLKSEL & 0x3)) {
case SYSCTL_MAINCLKSRC_IRC:
clkRate = Chip_Clock_GetIntOscRate();
break;
case SYSCTL_MAINCLKSRC_PLLIN:
clkRate = Chip_Clock_GetSystemPLLInClockRate();
break;
case SYSCTL_MAINCLKSRC_WDTOSC:
clkRate = Chip_Clock_GetWDTOSCRate();
break;
case SYSCTL_MAINCLKSRC_PLLOUT:
clkRate = Chip_Clock_GetSystemPLLOutClockRate();
break;
}
return clkRate;
}
/* Return system clock rate */
uint32_t Chip_Clock_GetSystemClockRate(void)
{
/* No point in checking for divide by 0 */
return Chip_Clock_GetMainClockRate() / (LPC_SYSCTL->SYSAHBCLKDIV & ~SYSCTL_SYSAHBCLKDIV_RESERVED);
}
/* Get USART 0/1/2 UART base rate */
uint32_t Chip_Clock_GetUSARTNBaseClockRate(void)
{
uint64_t inclk;
uint32_t div;
div = (uint32_t) Chip_Clock_GetUARTClockDiv();
if (div == 0) {
/* Divider is 0 so UART clock is disabled */
inclk = 0;
}
else {
uint32_t mult, divf;
/* Input clock into FRG block is the divided main system clock */
inclk = (uint64_t) (Chip_Clock_GetMainClockRate() / div);
divf = Chip_SYSCTL_GetUSARTFRGDivider();
if (divf == 0xFF) {
/* Fractional part is enabled, get multiplier */
mult = (uint32_t) Chip_SYSCTL_GetUSARTFRGMultiplier();
/* Get fractional error */
inclk = (inclk * 256) / (uint64_t) (256 + mult);
}
}
return (uint32_t) inclk;
}
/* Set USART 0/1/2 UART base rate */
uint32_t Chip_Clock_SetUSARTNBaseClockRate(uint32_t rate, bool fEnable)
{
uint32_t div, inclk;
/* Input clock into FRG block is the main system clock */
inclk = Chip_Clock_GetMainClockRate();
/* Get integer divider for coarse rate */
div = inclk / rate;
if (div == 0) {
div = 1;
}
/* Approximated rate with only integer divider */
Chip_Clock_SetUARTClockDiv((uint8_t) div);
if (fEnable) {
uint32_t uart_fra_multiplier;
/* Reset FRG */
Chip_SYSCTL_PeriphReset(RESET_UARTFBRG);
/* Enable fractional divider */
Chip_SYSCTL_SetUSARTFRGDivider(0xFF);
/* Compute the fractional divisor (the lower byte is the
fractional portion) */
uart_fra_multiplier = ((inclk / div) * 256) / rate;
/* ...just the fractional portion (the lower byte) */
Chip_SYSCTL_SetUSARTFRGMultiplier((uint8_t) uart_fra_multiplier);
}
else {
/* Disable fractional generator and use integer divider only */
Chip_SYSCTL_SetUSARTFRGDivider(0);
}
return Chip_Clock_GetUSARTNBaseClockRate();
}
/* Get the IOCONCLKDIV clock rate */
uint32_t Chip_Clock_GetIOCONCLKDIVClockRate(CHIP_PIN_CLKDIV_T reg)
{
uint32_t div = LPC_SYSCTL->IOCONCLKDIV[reg] & ~SYSCTL_IOCONCLKDIV_RESERVED;
uint32_t main_clk = Chip_Clock_GetMainClockRate();
return (div == 0) ? 0 : (main_clk / div);
}
void Chip_Clock_SetIOCONCLKDIV(CHIP_PIN_CLKDIV_T reg, uint8_t div)
{
int t_reg = IOCONCLK_MAX-reg;
LPC_SYSCTL->IOCONCLKDIV[t_reg] = div;
}

View File

@ -0,0 +1,453 @@
/*
* @brief LPC8xx clock driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __CLOCK_8XX_H_
#define __CLOCK_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CLOCK_8XX CHIP: LPC8xx Clock Driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/* Internal oscillator frequency */
#define SYSCTL_IRC_FREQ (12000000)
#ifndef MAX_CLOCK_FREQ
#define MAX_CLOCK_FREQ (30000000)
#endif
/**
* Clock sources for system and USB PLLs
*/
typedef enum CHIP_SYSCTL_PLLCLKSRC {
SYSCTL_PLLCLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCTL_PLLCLKSRC_SYSOSC, /*!< Crystal (system) oscillator */
SYSCTL_PLLCLKSRC_RESERVED,
SYSCTL_PLLCLKSRC_EXT_CLKIN, /*!< External clock input */
} CHIP_SYSCTL_PLLCLKSRC_T;
/**
* Watchdog oscillator analog output frequency selection
* values enum (plus or minus 40%)
*/
typedef enum CHIP_WDTLFO_OSC {
WDTLFO_OSC_ILLEGAL,
WDTLFO_OSC_0_60, /*!< 0.6 MHz watchdog/LFO rate */
WDTLFO_OSC_1_05, /*!< 1.05 MHz watchdog/LFO rate */
WDTLFO_OSC_1_40, /*!< 1.4 MHz watchdog/LFO rate */
WDTLFO_OSC_1_75, /*!< 1.75 MHz watchdog/LFO rate */
WDTLFO_OSC_2_10, /*!< 2.1 MHz watchdog/LFO rate */
WDTLFO_OSC_2_40, /*!< 2.4 MHz watchdog/LFO rate */
WDTLFO_OSC_2_70, /*!< 2.7 MHz watchdog/LFO rate */
WDTLFO_OSC_3_00, /*!< 3.0 MHz watchdog/LFO rate */
WDTLFO_OSC_3_25, /*!< 3.25 MHz watchdog/LFO rate */
WDTLFO_OSC_3_50, /*!< 3.5 MHz watchdog/LFO rate */
WDTLFO_OSC_3_75, /*!< 3.75 MHz watchdog/LFO rate */
WDTLFO_OSC_4_00, /*!< 4.0 MHz watchdog/LFO rate */
WDTLFO_OSC_4_20, /*!< 4.2 MHz watchdog/LFO rate */
WDTLFO_OSC_4_40, /*!< 4.4 MHz watchdog/LFO rate */
WDTLFO_OSC_4_60 /*!< 4.6 MHz watchdog/LFO rate */
} CHIP_WDTLFO_OSC_T;
/**
* Clock sources for main system clock
*/
typedef enum CHIP_SYSCTL_MAINCLKSRC {
SYSCTL_MAINCLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCTL_MAINCLKSRC_PLLIN, /*!< System PLL input */
SYSCTL_MAINCLKSRC_WDTOSC, /*!< Watchdog oscillator rate */
SYSCTL_MAINCLKSRC_PLLOUT, /*!< System PLL output */
} CHIP_SYSCTL_MAINCLKSRC_T;
/**
* System and peripheral clocks enum
*/
typedef enum CHIP_SYSCTL_CLOCK {
SYSCTL_CLOCK_SYS = 0, /*!< System clock */
SYSCTL_CLOCK_ROM, /*!< ROM clock */
SYSCTL_CLOCK_RAM, /*!< RAM clock */
SYSCTL_CLOCK_FLASHREG, /*!< FLASH register interface clock */
SYSCTL_CLOCK_FLASH, /*!< FLASH array access clock */
SYSCTL_CLOCK_I2C0, /*!< I2C0 clock */
SYSCTL_CLOCK_GPIO, /*!< GPIO clock */
SYSCTL_CLOCK_SWM, /*!< Switch matrix clock */
SYSCTL_CLOCK_SCT, /*!< State configurable timer clock */
SYSCTL_CLOCK_WKT, /*!< Self wake-up timer clock */
SYSCTL_CLOCK_MRT, /*!< Multi-rate timer clock */
SYSCTL_CLOCK_SPI0, /*!< SPI0 clock */
SYSCTL_CLOCK_SPI1, /*!< SPI01 clock */
SYSCTL_CLOCK_CRC, /*!< CRC clock */
SYSCTL_CLOCK_UART0, /*!< UART0 clock */
SYSCTL_CLOCK_UART1, /*!< UART1 clock */
SYSCTL_CLOCK_UART2, /*!< UART2 clock */
SYSCTL_CLOCK_WWDT, /*!< Watchdog clock */
SYSCTL_CLOCK_IOCON, /*!< IOCON clock */
SYSCTL_CLOCK_ACOMP, /*!< Analog comparator clock */
/* LPC82x Specific Clocks */
SYSCTL_CLOCK_I2C1 = 21, /*!< I2C1 Clock */
SYSCTL_CLOCK_I2C2, /*!< I2C2 Clock */
SYSCTL_CLOCK_I2C3, /*!< I2C3 Clock */
SYSCTL_CLOCK_ADC, /*!< 12-Bit ADC Clock */
SYSCTL_CLOCK_MTB = 26, /*!< Macro Trace Buffer [USED FOR DEBUGGING] */
SYSCTL_CLOCK_DMA = 29, /*!< DMA Clock */
} CHIP_SYSCTL_CLOCK_T;
/* Clock name alias */
#define SYSCTL_CLOCK_I2C SYSCTL_CLOCK_I2C0
#define SYSCTL_CLOCK_ACMP SYSCTL_CLOCK_ACOMP
/**
* Clock sources for CLKOUT
*/
typedef enum CHIP_SYSCTL_CLKOUTSRC {
SYSCTL_CLKOUTSRC_IRC = 0, /*!< Internal oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_SYSOSC, /*!< System oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_WDTOSC, /*!< Watchdog oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_MAINSYSCLK, /*!< Main system clock for CLKOUT */
} CHIP_SYSCTL_CLKOUTSRC_T;
/**
* @brief Set System PLL divider values
* @param msel : PLL feedback divider value
* @param psel : PLL post divider value
* @return Nothing
* @note See the user manual for how to setup the PLL
*/
STATIC INLINE void Chip_Clock_SetupSystemPLL(uint8_t msel, uint8_t psel)
{
LPC_SYSCTL->SYSPLLCTRL = (msel & 0x1F) | ((psel & 0x3) << 5);
}
/**
* @brief Read System PLL status
* @return true if the PLL is locked, false if not locked
*/
STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void)
{
return (bool) ((LPC_SYSCTL->SYSPLLSTAT & 1) != 0);
}
/**
* @brief Setup Watchdog oscillator rate and divider
* @param wdtclk : Selected watchdog clock rate
* @param div : Watchdog divider value, even value between 2 and 64
* @return Nothing
* @note Watchdog rate = selected rate divided by divider rate
*/
STATIC INLINE void Chip_Clock_SetWDTOSC(CHIP_WDTLFO_OSC_T wdtclk, uint8_t div)
{
LPC_SYSCTL->WDTOSCCTRL = (((uint32_t) wdtclk) << 5) | ((div >> 1) - 1);
}
/**
* @brief Returns the main clock source
* @return Main clock source
*/
STATIC INLINE CHIP_SYSCTL_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void)
{
return (CHIP_SYSCTL_MAINCLKSRC_T) (LPC_SYSCTL->MAINCLKSEL & ~SYSCTL_MAINCLKSEL_RESERVED);
}
/**
* @brief Set system clock divider
* @param div : divider for system clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The system clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div)
{
LPC_SYSCTL->SYSAHBCLKDIV = div;
}
/**
* @brief Enable system or peripheral clock
* @param clk : Clock to enable
* @return Nothing
*/
STATIC INLINE void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
{
LPC_SYSCTL->SYSAHBCLKCTRL = (1 << clk) | (LPC_SYSCTL->SYSAHBCLKCTRL & ~SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief Disable system or peripheral clock
* @param clk : Clock to disable
* @return Nothing
*/
STATIC INLINE void Chip_Clock_DisablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
{
LPC_SYSCTL->SYSAHBCLKCTRL &= ~((1 << clk) | SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief Set UART divider clock
* @param div : divider for UART clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The UART clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetUARTClockDiv(uint32_t div)
{
LPC_SYSCTL->UARTCLKDIV = div;
}
/**
* @brief Return UART divider
* @return divider for UART clock
* @note A value of 0 means the clock is disabled.
*/
STATIC INLINE uint32_t Chip_Clock_GetUARTClockDiv(void)
{
return LPC_SYSCTL->UARTCLKDIV & ~SYSCTL_UARTCLKDIV_RESERVED;
}
/**
* @brief Set The USART Fractional Generator Divider
* @param div : Fractional Generator Divider value, should be 0xFF
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_SetUSARTFRGDivider(uint8_t div)
{
LPC_SYSCTL->UARTFRGDIV = (uint32_t) div;
}
/**
* @brief Get The USART Fractional Generator Divider
* @return Value of USART Fractional Generator Divider
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetUSARTFRGDivider(void)
{
return LPC_SYSCTL->UARTFRGDIV & ~SYSCTL_UARTFRGDIV_RESERVED;
}
/**
* @brief Set The USART Fractional Generator Multiplier
* @param mult : An 8-bit value (0-255) U_PCLK = UARTCLKDIV/(1 + MULT/256)
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_SetUSARTFRGMultiplier(uint8_t mult)
{
LPC_SYSCTL->UARTFRGMULT = (uint32_t) mult;
}
/**
* @brief Get The USART Fractional Generator Multiplier
* @return Value of USART Fractional Generator Multiplier
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetUSARTFRGMultiplier(void)
{
return LPC_SYSCTL->UARTFRGMULT & ~SYSCTL_UARTFRGMULT_RESERVED;
}
/**
* @brief Set USART 0/1/2 UART base rate (up to main clock rate)
* @param rate : Desired rate for fractional divider/multipler output
* @param fEnable : true to use fractional clocking, false for integer clocking
* @return Actual rate generated
* @note USARTs 0 - 2 use the same base clock for their baud rate
* basis. This function is used to generate that clock, while the
* UART driver's SetBaud functions will attempt to get the closest
* baud rate from this base clock without altering it. This needs
* to be setup prior to individual UART setup.<br>
* UARTs need a base clock 16x faster than the baud rate, so if you
* need a 115.2Kbps baud rate, you will need a clock rate of at
* least (115.2K * 16). The UART base clock is generated from the
* main system clock, so fractional clocking may be the only
* possible choice when using a low main system clock frequency.
* Do not alter the FRGCLKDIV register after this call.
*/
uint32_t Chip_Clock_SetUSARTNBaseClockRate(uint32_t rate, bool fEnable);
/**
* @brief Get USART 0/1/2 UART base rate
* @return USART 0/1/2 UART base rate
*/
uint32_t Chip_Clock_GetUSARTNBaseClockRate(void);
/**
* @brief Returns the main oscillator clock rate
* @return main oscillator clock rate
*/
STATIC INLINE uint32_t Chip_Clock_GetMainOscRate(void)
{
return OscRateIn;
}
/**
* @brief Returns the internal oscillator (IRC) clock rate
* @return internal oscillator (IRC) clock rate
*/
STATIC INLINE uint32_t Chip_Clock_GetIntOscRate(void)
{
return SYSCTL_IRC_FREQ;
}
/**
* @brief Returns the external clock input rate
* @return External clock input rate
*/
STATIC INLINE uint32_t Chip_Clock_GetExtClockInRate(void)
{
return ExtRateIn;
}
/**
* @brief Set System PLL clock source
* @param src : Clock source for system PLL
* @return Nothing
* @note This function will also toggle the clock source update register
* to update the clock source
*/
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src);
/**
* @brief Bypass System Oscillator and set oscillator frequency range
* @param bypass : Flag to bypass oscillator
* @param highfr : Flag to set oscillator range from 15-25 MHz
* @return Nothing
* @note Sets the PLL input to bypass the oscillator. This would be
* used if an external clock that is not an oscillator is attached
* to the XTALIN pin.
*/
void Chip_Clock_SetPLLBypass(bool bypass, bool highfr);
/**
* @brief Set main system clock source
* @param src : Clock source for main system
* @return Nothing
* @note This function will also toggle the clock source update register
* to update the clock source
*/
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src);
/**
* @brief Set CLKOUT clock source and divider
* @param src : Clock source for CLKOUT
* @param div : divider for CLKOUT clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The CLKOUT clock
* rate is the clock source divided by the divider. This function will
* also toggle the clock source update register to update the clock
* source.
*/
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div);
/**
* @brief Return estimated watchdog oscillator rate
* @return Estimated watchdog oscillator rate
* @note This rate is accurate to plus or minus 40%.
*/
uint32_t Chip_Clock_GetWDTOSCRate(void);
/**
* @brief Return System PLL input clock rate
* @return System PLL input clock rate
*/
uint32_t Chip_Clock_GetSystemPLLInClockRate(void);
/**
* @brief Return System PLL output clock rate
* @return System PLL output clock rate
*/
uint32_t Chip_Clock_GetSystemPLLOutClockRate(void);
/**
* @brief Return main clock rate
* @return main clock rate
*/
uint32_t Chip_Clock_GetMainClockRate(void);
/**
* @brief Return system clock rate
* @return system clock rate
*/
uint32_t Chip_Clock_GetSystemClockRate(void);
/**
* @brief Get IOCONCLKDIV clock rate
* @param reg : Divider register to get
* @return The clock rate going to the IOCON glitch filter
* @note Use 0 to disable, or a divider value of 1 to 255.
*/
uint32_t Chip_Clock_GetIOCONCLKDIVClockRate(CHIP_PIN_CLKDIV_T reg);
/**
* @brief Set IOCONCLKDIV divider
* @param reg : divider register to set
* @param div : divider value for IOCONCLKDIV[reg] clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255.
*/
void Chip_Clock_SetIOCONCLKDIV(CHIP_PIN_CLKDIV_T reg, uint8_t div);
/**
* @}
*/
/** @defgroup IRC_8XX CHIP: LPC8xx IRC Configuration
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief set main / system clock using IRC and PLL
* @param main: main clock frequency (in MHz)
* @param sys : system clock frequency (in MHz)
* @return bool: Success = true / fail = false
* @note This is a table based function. The table uses both the
* main frequency and the system frequency to set the PLL.
* All useful main / system clock combinations are in the table.
* See irc_8xx.c for details.
*/
bool Chip_IRC_SetFreq(uint32_t main, uint32_t sys);
/**
* @brief Set main / system clock using IRC and PLL
* @param sys : system clock frequency (in MHz)
* @return Nothing
* @note This function uses the ROM set_pll() function.
*/
void Chip_IRC_SetFreq_ROM(uint32_t sys);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CLOCK_8XX_H_ */

View File

@ -0,0 +1,160 @@
/*
* @brief Basic CMSIS include file
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __CMSIS_H_
#define __CMSIS_H_
#include "lpc_types.h"
// >>> system config
#define CHIP_LPC8XX
#define CHIP_LPC82X
// <<<
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CMSIS_8XX_ALL CHIP: LPC8xx CMSIS include file
* @ingroup CHIP_8XX_Drivers
* @{
*/
#if defined(__ARMCC_VERSION)
// Kill warning "#pragma push with no matching #pragma pop"
#pragma diag_suppress 2525
#pragma push
#pragma anon_unions
#elif defined(__CWCC__)
#pragma push
#pragma cpp_extensions on
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__IAR_SYSTEMS_ICC__)
// #pragma push // FIXME not usable for IAR
#pragma language=extended
#else
#error Not supported compiler type
#endif
#if !defined(CORE_M0PLUS)
#error Please #define CORE_M0PLUS
#endif
/** @defgroup CMSIS_8XX CHIP: LPC8xx Cortex CMSIS definitions
* @ingroup CMSIS_8XX_ALL
* @{
*/
/* Configuration of the Cortex-M0+ Processor and Core Peripherals */
#define __CM0PLUS_REV 0x0001 /*!< Cortex-M0+ Core Revision */
#define __MPU_PRESENT 0 /*!< MPU present or not */
#define __VTOR_PRESENT 1 /*!< VTOR is present in this implementation */
#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/**
* @}
*/
/** @defgroup CMSIS_8XX_IRQ CHIP: LPC8xx peripheral interrupt numbers
* @ingroup CMSIS_8XX_ALL
* @{
*/
typedef enum {
/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
/****** LPC8xx Specific Interrupt Numbers ********************************************************/
SPI0_IRQn = 0, /*!< SPI0 */
SPI1_IRQn = 1, /*!< SPI1 */
Reserved0_IRQn = 2, /*!< Reserved Interrupt */
UART0_IRQn = 3, /*!< USART0 */
UART1_IRQn = 4, /*!< USART1 */
UART2_IRQn = 5, /*!< USART2 */
Reserved1_IRQn = 6, /*!< Reserved Interrupt */
I2C1_IRQn = 7, /*!< I2C1 */
I2C0_IRQn = 8, /*!< I2C0 */
I2C_IRQn = 8, /*!< Alias for I2C0 */
SCT_IRQn = 9, /*!< SCT */
MRT_IRQn = 10, /*!< MRT */
CMP_IRQn = 11, /*!< CMP */
WDT_IRQn = 12, /*!< WDT */
BOD_IRQn = 13, /*!< BOD */
FLASH_IRQn = 14, /*!< Flash interrupt */
WKT_IRQn = 15, /*!< WKT Interrupt */
ADC_SEQA_IRQn = 16, /*!< ADC sequence A completion */
ADC_SEQB_IRQn = 17, /*!< ADC sequence B completion */
ADC_THCMP_IRQn = 18, /*!< ADC threshold compare */
ADC_OVR_IRQn = 19, /*!< ADC overrun */
DMA_IRQn = 20, /*!< Reserved Interrupt */
I2C2_IRQn = 21, /*!< Reserved Interrupt */
I2C3_IRQn = 22, /*!< Reserved Interrupt */
Reserved2_IRQn = 23, /*!< Reserved Interrupt */
PININT0_IRQn = 24, /*!< External Interrupt 0 */
PIN_INT0_IRQn = 24, /*!< External Interrupt 0 (alias) */
PININT1_IRQn = 25, /*!< External Interrupt 1 */
PIN_INT1_IRQn = 25, /*!< External Interrupt 1 (alias) */
PININT2_IRQn = 26, /*!< External Interrupt 2 */
PIN_INT2_IRQn = 26, /*!< External Interrupt 2 (alias) */
PININT3_IRQn = 27, /*!< External Interrupt 3 */
PIN_INT3_IRQn = 27, /*!< External Interrupt 3 (alias) */
PININT4_IRQn = 28, /*!< External Interrupt 4 */
PIN_INT4_IRQn = 28, /*!< External Interrupt 4 (alias) */
PININT5_IRQn = 29, /*!< External Interrupt 5 */
PIN_INT5_IRQn = 29, /*!< External Interrupt 5 (alias) */
PININT6_IRQn = 30, /*!< External Interrupt 6 */
PIN_INT6_IRQn = 30, /*!< External Interrupt 6 (alias) */
PININT7_IRQn = 31, /*!< External Interrupt 7 */
PIN_INT7_IRQn = 31, /*!< External Interrupt 7 (alias) */
} IRQn_Type;
/**
* @}
*/
#include "core_cm0plus.h" /*!< Cortex-M0+ processor and core peripherals */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CMSIS_H_ */

View File

@ -0,0 +1,100 @@
/*
* @brief Error code returned by LPC8xx Boot ROM drivers/library functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ERROR_8XX_H__
#define __ERROR_8XX_H__
/** @defgroup ROMAPI_ERRORCODES_8XX CHIP: LPC8xx ROM API error codes
* @ingroup ROMAPI_8XX
* @{
*/
/** Error code returned by Boot ROM drivers/library functions
*
* Error codes are a 32-bit value with :
* - The 16 MSB contains the peripheral code number
* - The 16 LSB contains an error code number associated to that peripheral
*
*/
typedef enum
{
/**\b 0x00000000*/ LPC_OK = 0, /**< enum value returned on Successful completion */
/**\b 0x00000001*/ LPC_ERROR, /**< enum value returned on general error (I2C) */
/* ISP related errors */
ERR_ISP_BASE = 0x00000000,
/**\b 0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1,
/**\b 0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /*!< Source address not on word boundary */
/**\b 0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /*!< Destination address not on word or 256 byte boundary */
/**\b 0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED,
/**\b 0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED,
/**\b 0x00000006*/ ERR_ISP_COUNT_ERROR, /*!< Byte count is not multiple of 4 or is not a permitted value */
/**\b 0x00000007*/ ERR_ISP_INVALID_SECTOR,
/**\b 0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK,
/**\b 0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
/**\b 0x0000000A*/ ERR_ISP_COMPARE_ERROR,
/**\b 0x0000000B*/ ERR_ISP_BUSY, /*!< Flash programming hardware interface is busy */
/**\b 0x0000000C*/ ERR_ISP_PARAM_ERROR, /*!< Insufficient number of parameters */
/**\b 0x0000000D*/ ERR_ISP_ADDR_ERROR, /*!< Address not on word boundary */
/**\b 0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED,
/**\b 0x0000000F*/ ERR_ISP_CMD_LOCKED, /*!< Command is locked */
/**\b 0x00000010*/ ERR_ISP_INVALID_CODE, /*!< Unlock code is invalid */
/**\b 0x00000011*/ ERR_ISP_INVALID_BAUD_RATE,
/**\b 0x00000012*/ ERR_ISP_INVALID_STOP_BIT,
/**\b 0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED,
/* I2C related errors */
ERR_I2C_BASE = 0x00060000,
/**\b 0x00060001*/ ERR_I2C_NAK = ERR_I2C_BASE + 1, /*!< NAK */
/**\b 0x00060002*/ ERR_I2C_BUFFER_OVERFLOW, /*!< Buffer overflow */
/**\b 0x00060003*/ ERR_I2C_BYTE_COUNT_ERR, /*!< Byte count error */
/**\b 0x00060004*/ ERR_I2C_LOSS_OF_ARBRITRATION, /*!< Loss of arbitration */
/**\b 0x00060005*/ ERR_I2C_SLAVE_NOT_ADDRESSED, /*!< Slave not addressed */
/**\b 0x00060006*/ ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT, /*!< Loss arbritation NAK */
/**\b 0x00060007*/ ERR_I2C_GENERAL_FAILURE, /*!< General failure */
/**\b 0x00060008*/ ERR_I2C_REGS_SET_TO_DEFAULT, /*!< Set to default */
/**\b 0x00060009*/ ERR_I2C_TIMEOUT, /*!< I2C Timeout */
/* UART related errors */
/**\b 0x00080001*/ ERR_NO_ERROR = LPC_OK, /*!< Receive is busy */
ERR_UART_BASE = 0x00080000,
/**\b 0x00080001*/ ERR_UART_RXD_BUSY = ERR_UART_BASE + 1, /*!< Receive is busy */
/**\b 0x00080002*/ ERR_UART_TXD_BUSY, /*!< Transmit is busy */
/**\b 0x00080003*/ ERR_UART_OVERRUN_FRAME_PARITY_NOISE, /*!< Overrun, Frame, Parity , Receive Noise error */
/**\b 0x00080004*/ ERR_UART_UNDERRUN, /*!< Underrun */
/**\b 0x00080005*/ ERR_UART_PARAM, /*!< Parameter error */
} ErrorCode_t;
/**
* @}
*/
#endif /* __ERROR_8XX_H__ */

View File

@ -0,0 +1,146 @@
/*
* @brief LPC8xx FLASH Memory Controller (FMC) driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __FMC_8XX_H_
#define __FMC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup FMC_8XX CHIP: LPC8xx FLASH Memory Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief FLASH Memory Controller Unit register block structure
*/
typedef struct {
__I uint32_t RESERVED1[4];
__IO uint32_t FLASHCFG; /*!< Flash Configuration register */
__I uint32_t RESERVED2[3];
__IO uint32_t FMSSTART; /*!< Signature start address register */
__IO uint32_t FMSSTOP; /*!< Signature stop address register */
__I uint32_t RESERVED3;
__I uint32_t FMSW[1]; /*!< Signature word regsiter */
} LPC_FMC_T;
/* Reserved bits masks for registers */
#define FMC_FLASHCFG_RESERVED (~3)
#define FMC_FMSSTART_RESERVED 0xfffe0000
#define FMC_FMSSTOP_RESERVED 0x7ffe0000
/**
* @brief FLASH Access time definitions
*/
typedef enum {
FLASHTIM_20MHZ_CPU = 0, /*!< Flash accesses use 1 CPU clocks. Use for up to 20 MHz CPU clock*/
FLASHTIM_30MHZ_CPU = 1, /*!< Flash accesses use 2 CPU clocks. Use for up to 30 MHz CPU clock*/
} FMC_FLASHTIM_T;
/**
* @brief Set FLASH memory access time in clocks
* @param clks : Clock cycles for FLASH access
* @return Nothing
* @note For CPU speed up to 20MHz, use a value of 0. For up to 30MHz, use
* a value of 1
*/
STATIC INLINE void Chip_FMC_SetFLASHAccess(FMC_FLASHTIM_T clks)
{
uint32_t tmp = LPC_FMC->FLASHCFG & (~((0x3)|FMC_FLASHCFG_RESERVED));
/* Don't alter upper bits */
LPC_FMC->FLASHCFG = tmp | clks;
}
/* Flash signature start and busy status bit */
#define FMC_FLASHSIG_BUSY (1UL << 31)
/**
* @brief Start computation of a signature for a FLASH memory range
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param stop : Ending FLASH address for computation, must be aligned on 16 byte boundary
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignature(uint32_t start, uint32_t stop)
{
LPC_FMC->FMSSTART = (start >> 4);
LPC_FMC->FMSSTOP = (stop >> 4) | FMC_FLASHSIG_BUSY;
}
/**
* @brief Start computation of a signature for a FLASH memory address and block count
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param blocks : Number of 16 byte blocks used for computation
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignatureBlocks(uint32_t start, uint32_t blocks)
{
Chip_FMC_ComputeSignature(start, (start + (blocks * 16)));
}
/**
* @brief Check for signature geenration completion
* @return true if the signature computation is running, false if finished
*/
STATIC INLINE bool Chip_FMC_IsSignatureBusy(void)
{
return (bool) ((LPC_FMC->FMSSTOP & FMC_FLASHSIG_BUSY) != 0);
}
/**
* @brief Returns the generated FLASH signature value
* @param index : Signature index, must be 0
* @return the generated FLASH signature value
*/
STATIC INLINE uint32_t Chip_FMC_GetSignature(int index)
{
return LPC_FMC->FMSW[index];
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __FMC_8XX_H_ */

View File

@ -0,0 +1,152 @@
/*
* @brief LPC8xx IOCON driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#define _CHIP_COMMON_
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#define PINASSIGN_IDX(movable) (((movable) >> 4))
#define PINSHIFT(movable) (((movable) & 0xF) << 3)
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Set the pin mode (pull-up/pull-down). */
void Chip_IOCON_PinSetMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_MODE_T mode)
{
uint32_t reg;
reg = pIOCON->PIO0[pin] & ~(PIN_MODE_MASK);
pIOCON->PIO0[pin] = reg | (mode << PIN_MODE_BITNUM);
}
/* Enables/disables the pin hysteresis. */
void Chip_IOCON_PinSetHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool enable)
{
if (enable == true) {
Chip_IOCON_PinEnableHysteresis(pIOCON, pin);
}
else {
Chip_IOCON_PinDisableHysteresis(pIOCON, pin);
}
}
/*Inverts (or not) the input seen by a pin. */
void Chip_IOCON_PinSetInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool invert)
{
if (invert == true) {
Chip_IOCON_PinEnableInputInverted(pIOCON, pin);
}
else {
Chip_IOCON_PinDisableInputInverted(pIOCON, pin);
}
}
/* Enables/disables Open-Drain mode for a pin. */
void Chip_IOCON_PinSetOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool open_drain)
{
if (open_drain == true) {
Chip_IOCON_PinEnableOpenDrainMode(pIOCON, pin);
}
else {
Chip_IOCON_PinDisableOpenDrainMode(pIOCON, pin);
}
}
/* Enable/configure digital filter sample mode for a pin. */
void Chip_IOCON_PinSetSampleMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_SMODE_T smode)
{
uint32_t reg;
reg = pIOCON->PIO0[pin] & ~(PIN_SMODE_MASK);
pIOCON->PIO0[pin] = reg | (smode << PIN_SMODE_BITNUM);
}
/* Set the peripheral clock divisor for a pin. */
void Chip_IOCON_PinSetClockDivisor(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_CLKDIV_T clkdiv)
{
uint32_t reg;
reg = pIOCON->PIO0[pin] & ~(PIN_CLKDIV_MASK);
pIOCON->PIO0[pin] = reg | (clkdiv << PIN_CLKDIV_BITNUM);
}
/* Set the I2C mode for a pin. */
void Chip_IOCON_PinSetI2CMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_I2CMODE_T mode)
{
uint32_t reg;
/* I2C mode bits only for I2C pins */
reg = pIOCON->PIO0[pin] & ~(PIN_I2CMODE_MASK);
pIOCON->PIO0[pin] = reg | (mode << PIN_I2CMODE_BITNUM);
}
/* Set all I/O Control pin muxing */
void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T* pinArray, uint32_t arrayLength)
{
uint32_t ix;
for (ix = 0; ix < arrayLength; ix++ ) {
Chip_IOCON_PinMuxSet(pIOCON, pinArray[ix].pin, pinArray[ix].modefunc);
}
}
/* assign a movable pin function to a physical pin */
void Chip_SWM_MovablePinAssign(CHIP_SWM_PIN_MOVABLE_T movable, uint8_t pin)
{
uint32_t temp;
int pinshift = PINSHIFT(movable), regIndex = PINASSIGN_IDX(movable);
temp = LPC_SWM->PINASSIGN[regIndex] & (~(0xFF << pinshift));
LPC_SWM->PINASSIGN[regIndex] = temp | (pin << pinshift);
}
/* true enables, false disables a Switch Matrix fixed-pin Function */
void Chip_SWM_FixedPinEnable(CHIP_SWM_PIN_FIXED_T pin, bool enable)
{
if (enable) {
Chip_SWM_EnableFixedPin(pin);
}
else {
Chip_SWM_DisableFixedPin(pin);
}
}

View File

@ -0,0 +1,601 @@
/*
* @brief LPC8xx IOCON register block and driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __IOCON_8XX_H_
#define __IOCON_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup IOCON_8XX CHIP: LPC8xx IOCON register block and driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
#define NUM_IOCON_PIO (29)
/**
* @brief Array of IOCON pin definitions passed to Chip_IOCON_SetPinMuxing() must be in this format
*/
typedef struct {
uint32_t pin:8; /* Pin number */
uint32_t modefunc:24; /* Function and mode */
} PINMUX_GRP_T;
/**
* @brief IOCON register block structure
* @note When accessing this register structure, use the PIOn enumeration
* as the array index as the pin assignments are not mapped 1-1 with the
* IOCON structure.<br>
* Incorrect: LPC_IOCON->PIO0[0] = 0x1; // Index 0 does not map to pin 0!<br>
* Correct: LPC_IOCON->PIO0[IOCON_PIO0] = 0x1; // Enumeration PIO0 maps to pin 0
*/
typedef struct { /*!< (@ 0x40044000) IOCONFIG Structure */
__IO uint32_t PIO0[NUM_IOCON_PIO + 2]; /* 2 added for reserved register */
} LPC_IOCON_T;
/**
* @brief IOCON Register bit definitions
*/
/* Pin Mode mask */
#define PIN_MODE_MASK (0x3 << 3)
#define PIN_MODE_BITNUM (3)
/* Pin Hysteresis mask */
#define PIN_HYS_MASK (0x1 << 5)
#define PIN_HYS_BITNUM (5)
/* Pin invert input mask */
#define PIN_INV_MASK (0x1 << 6)
#define PIN_INV_BITNUM (6)
/* Pin open drain mode mask */
#define PIN_OD_MASK (0x1 << 10)
#define PIN_OD_BITNUM (10)
/* Pin digital filter sample mode mask */
#define PIN_SMODE_MASK (0x3 << 11)
#define PIN_SMODE_BITNUM (11)
/* Pin clock divider mask */
#define PIN_CLKDIV_MASK (0x7 << 13)
#define PIN_CLKDIV_BITNUM (13)
/* Pin I2C mode mask - valid for PIO10 & PIO11 only */
#define PIN_I2CMODE_MASK (0x3 << 8)
#define PIN_I2CMODE_BITNUM (8)
/**
* @brief IOCON Pin Numbers enum
* Maps a pin number to an IOCON (register) array index. IOCON indexes
* are not mapped 1-1 with pin numbers. When access the PIO0 array in
* the LPC_IOCON_T structure, the array should be indexed with one of
* these enumerations based on the pin that will have it's settings
* changed.<br>
* Example: LPC_IOCON->PIO0[IOCON_PIO0] = 0x1; // Enumeration PIO0 maps to pin 0
*/
typedef enum CHIP_PINx {
IOCON_PIO0 = 0x11, /*!< PIN 0 */
IOCON_PIO1 = 0x0B, /*!< PIN 1 */
IOCON_PIO2 = 0x06, /*!< PIN 2 */
IOCON_PIO3 = 0x05, /*!< PIN 3 */
IOCON_PIO4 = 0x04, /*!< PIN 4 */
IOCON_PIO5 = 0x03, /*!< PIN 5 */
/* The following pins are not present in DIP8 packages */
IOCON_PIO6 = 0x10, /*!< PIN 6 */
IOCON_PIO7 = 0x0F, /*!< PIN 7 */
IOCON_PIO8 = 0x0E, /*!< PIN 8 */
IOCON_PIO9 = 0x0D, /*!< PIN 9 */
IOCON_PIO10 = 0x08, /*!< PIN 10 */
IOCON_PIO11 = 0x07, /*!< PIN 11 */
IOCON_PIO12 = 0x02, /*!< PIN 12 */
IOCON_PIO13 = 0x01, /*!< PIN 13 */
/* The following pins are not present in DIP8 & TSSOP16 packages */
IOCON_PIO14 = 0x12, /*!< PIN 14 */
IOCON_PIO15 = 0x0A, /*!< PIN 15 */
IOCON_PIO16 = 0x09, /*!< PIN 16 */
IOCON_PIO17 = 0x00, /*!< PIN 17 */
IOCON_PIO_NUL0 = 0x0C, /*!< PIN NULL */
/* The following pins are not present in DIP8, TSSOP16 & TSSOP20 packages */
IOCON_PIO18 = 0x1E, /*!< PIN 18 */
IOCON_PIO19 = 0x1D, /*!< PIN 19 */
IOCON_PIO20 = 0x1C, /*!< PIN 20 */
IOCON_PIO21 = 0x1B, /*!< PIN 21 */
IOCON_PIO22 = 0x1A, /*!< PIN 22 */
IOCON_PIO23 = 0x19, /*!< PIN 23 */
IOCON_PIO24 = 0x18, /*!< PIN 24 */
IOCON_PIO25 = 0x17, /*!< PIN 25 */
IOCON_PIO26 = 0x16, /*!< PIN 26 */
IOCON_PIO27 = 0x15, /*!< PIN 27 */
IOCON_PIO28 = 0x14, /*!< PIN 28 */
IOCON_PIO_NUL1 = 0x13, /*!< PIN NULL */
} CHIP_PINx_T;
/**
* @brief IOCON Pin Modes enum
*/
typedef enum CHIP_PIN_MODE {
PIN_MODE_INACTIVE = 0, /*!< Inactive mode */
PIN_MODE_PULLDN = 1, /*!< Pull Down mode */
PIN_MODE_PULLUP = 2, /*!< Pull up mode */
PIN_MODE_REPEATER = 3 /*!< Repeater mode */
} CHIP_PIN_MODE_T;
/**
* @brief IOCON Digital Filter Sample modes enum
*/
typedef enum CHIP_PIN_SMODE {
PIN_SMODE_BYPASS = 0, /*!< Bypass input filter */
PIN_SMODE_CYC1 = 1, /*!< Input pulses shorter than 1 filter clock cycle are rejected */
PIN_SMODE_CYC2 = 2, /*!< Input pulses shorter than 2 filter clock cycles are rejected */
PIN_SMODE_CYC3 = 3 /*!< Input pulses shorter than 3 filter clock cycles are rejected */
} CHIP_PIN_SMODE_T;
/**
* @brief IOCON I2C Modes enum (Only for I2C pins PIO0_10 and PIO0_11)
*/
typedef enum CHIP_PIN_I2CMODE {
PIN_I2CMODE_STDFAST = 0, /*!< I2C standard mode/Fast mode */
PIN_I2CMODE_GPIO = 1, /*!< Standard I/O functionality */
PIN_I2CMODE_FASTPLUS = 2 /*!< I2C Fast plus mode */
} CHIP_PIN_I2CMODE_T;
/**
* @brief Sets I/O Control pin mux
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : GPIO pin to mux
* @param modefunc : OR'ed values or type IOCON_*
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinMuxSet(LPC_IOCON_T *pIOCON, uint8_t pin, uint32_t modefunc)
{
pIOCON->PIO0[pin] = modefunc;
}
/**
* @brief Set all I/O Control pin muxing
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pinArray : Pointer to array of pin mux selections
* @param arrayLength : Number of entries in pinArray
* @return Nothing
*/
void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T* pinArray, uint32_t arrayLength);
/**
* @brief Sets pull-up or pull-down mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param mode : Mode (Pull-up/Pull-down mode)
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
void Chip_IOCON_PinSetMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_MODE_T mode);
/**
* @brief Enable or disable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param enable : true to enable, false to disable
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
void Chip_IOCON_PinSetHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool enable);
/**
* @brief Enable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
STATIC INLINE void Chip_IOCON_PinEnableHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_HYS_MASK;
}
/**
* @brief Disable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
STATIC INLINE void Chip_IOCON_PinDisableHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_HYS_MASK;
}
/**
* @brief Enable or disable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param invert : true to invert, false to not to invert
* @return Nothing
*/
void Chip_IOCON_PinSetInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool invert);
/**
* @brief Enable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinEnableInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_INV_MASK;
}
/**
* @brief Disable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinDisableInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_INV_MASK;
}
/**
* @brief Enables or disables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param open_drain : true to enable open-drain mode,
* false to disable open-drain mode
* @return Nothing
*/
void Chip_IOCON_PinSetOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool open_drain);
/**
* @brief Enables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinEnableOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_OD_MASK;
}
/**
* @brief Disables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinDisableOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_OD_MASK;
}
/**
* @brief Set pin mode to default after reset
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinSetToDefault(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
if (pin == IOCON_PIO10 || pin == IOCON_PIO11)
pIOCON->PIO0[pin] = 0x80;
else
pIOCON->PIO0[pin] = 0x90;
}
/**
* @brief Sets the digital filter sampling mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param smode : 0x0 = bypass, 0x[1..3] = 1 to 3 clock cycles.
* @return Nothing
*/
void Chip_IOCON_PinSetSampleMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_SMODE_T smode);
/**
* @brief Select peripheral clock divider for input filter sampling clock
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param clkdiv : 0 = no divisor, 1...6 = PCLK/clkdiv
* @return Nothing
*/
void Chip_IOCON_PinSetClockDivisor(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_CLKDIV_T clkdiv);
/**
* @brief Set I2C mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param mode : 0:Standard/Fast I2C 1: GPIO 2: Fast Plus
* @return Nothing
* @note Valid for pins PIO0_10 and PIO0_11 only.
*/
void Chip_IOCON_PinSetI2CMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_I2CMODE_T mode);
/**
* @}
*/
/** @defgroup SWM_8XX CHIP: LPC8xx Switch Matrix Driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8XX Switch Matrix register block structure
*/
typedef struct {
#if defined(CHIP_LPC82X)
__IO uint32_t PINASSIGN[12]; /*!< Pin Assign register array */
__I uint32_t RESERVED0[100];
#else
__IO uint32_t PINASSIGN[9]; /*!< Pin Assign register array */
__I uint32_t RESERVED0[103];
#endif
__IO uint32_t PINENABLE0; /*!< Pin Enable register */
} LPC_SWM_T;
#if defined(CHIP_LPC82X)
#define SWM_PINENABLE0_RESERVED (~0x1ffffff)
#else
#define SWM_PINENABLE0_RESERVED (~0x1ff)
#endif
/**
* @brief LPC8XX Switch Matrix Movable pins
*/
#if defined(CHIP_LPC82X)
typedef enum CHIP_SWM_PIN_MOVABLE {
SWM_U0_TXD_O, /*!< PINASSIGN0 - UART0 TXD Output */
SWM_U0_RXD_I, /*!< PINASSIGN0 - UART0 RXD Input */
SWM_U0_RTS_O, /*!< PINASSIGN0 - UART0 RTS Output */
SWM_U0_CTS_I, /*!< PINASSIGN0 - UART0 CTS Input */
SWM_U0_SCLK_IO = 0x10, /*!< PINASSIGN1 - UART0 SCLK I/O */
SWM_U1_TXD_O, /*!< PINASSIGN1 - UART1 TXD Output */
SWM_U1_RXD_I, /*!< PINASSIGN1 - UART1 RXD Input */
SWM_U1_RTS_O, /*!< PINASSIGN1 - UART1 RTS Output */
SWM_U1_CTS_I = 0x20, /*!< PINASSIGN2 - UART1 CTS Input */
SWM_U1_SCLK_IO, /*!< PINASSIGN2 - UART1 SCLK I/O */
SWM_U2_TXD_O, /*!< PINASSIGN2 - UART2 TXD Output */
SWM_U2_RXD_I, /*!< PINASSIGN2 - UART2 RXD Input */
SWM_U2_RTS_O = 0x30, /*!< PINASSIGN3 - UART2 RTS Output */
SWM_U2_CTS_I, /*!< PINASSIGN3 - UART2 CTS Input */
SWM_U2_SCLK_IO, /*!< PINASSIGN3 - UART2 SCLK I/O */
SWM_SPI0_SCK_IO, /*!< PINASSIGN3 - SPI0 SCK I/O */
SWM_SPI0_MOSI_IO = 0x40, /*!< PINASSIGN4 - SPI0 MOSI I/O */
SWM_SPI0_MISO_IO, /*!< PINASSIGN4 - SPI0 MISO I/O */
SWM_SPI0_SSEL0_IO, /*!< PINASSIGN4 - SPI0 SSEL0 I/O */
SWM_SPI0_SSEL1_IO, /*!< PINASSIGN4 - SPI0 SSEL1 I/O */
SWM_SPI0_SSEL2_IO = 0x50, /*!< PINASSIGN5 - SPI0 SSEL2 I/O */
SWM_SPI0_SSEL3_IO, /*!< PINASSIGN5 - SPI0 SSEL3 I/O */
SWM_SPI1_SCK_IO, /*!< PINASSIGN5 - SPI1 SCK I/O */
SWM_SPI1_MOSI_IO, /*!< PINASSIGN5 - SPI1 MOSI I/O */
SWM_SPI1_MISO_IO = 0x60, /*!< PINASSIGN6 - SPI1 MISO I/O */
SWM_SPI1_SSEL0_IO, /*!< PINASSIGN6 - SPI1 SSEL0 I/O */
SWM_SPI1_SSEL1_IO, /*!< PINASSIGN6 - SPI1 SSEL1 I/O */
SWM_SCT_IN0_I, /*!< PINASSIGN6 - SCT INPUT_0 Input */
SWM_SCT_IN1_I = 0x70, /*!< PINASSIGN7 - SCT INPUT_1 Input */
SWM_SCT_IN2_I, /*!< PINASSIGN7 - SCT INPUT_2 Input */
SWM_SCT_IN3_I, /*!< PINASSIGN7 - SCT INPUT_3 Input */
SWM_SCT_OUT0_O, /*!< PINASSIGN7 - SCT OUTPUT_0 Output */
SWM_SCT_OUT1_O = 0x80, /*!< PINASSIGN8 - SCT OUTPUT_1 Output */
SWM_SCT_OUT2_O, /*!< PINASSIGN8 - SCT OUTPUT_2 Output */
SWM_SCT_OUT3_O, /*!< PINASSIGN8 - SCT OUTPUT_3 Output */
SWM_SCT_OUT4_O, /*!< PINASSIGN8 - SCT OUTPUT_4 Output */
SWM_SCT_OUT5_O = 0x90, /*!< PINASSIGN9 - SCT OUTPUT_5 Output */
SWM_I2C1_SDA_IO, /*!< PINASSIGN9 - I2C1 SDA I/O */
SWM_I2C1_SCL_IO, /*!< PINASSIGN9 - I2C1 SCL I/O */
SWM_I2C2_SDA_IO, /*!< PINASSIGN9 - I2C2 SDA I/O */
SWM_I2C2_SCL_IO = 0xA0, /*!< PINASSIGN10 - I2C2 SCL I/O */
SWM_I2C3_SDA_IO, /*!< PINASSIGN10 - I2C3 SDA I/O */
SWM_I2C3_SCL_IO, /*!< PINASSIGN10 - I2C3 SCL I/O */
SWM_ADC_PINTRIG0_I, /*!< PINASSIGN10 - ADC PIN TRIGGER-0 Input */
SWM_ADC_PINTRIG1_I = 0xB0, /*!< PINASSIGN11 - ADC PIN TRIGGER-1 Input */
SWM_ACMP_O_O, /*!< PINASSIGN11 - ACMP OUT Output */
SWM_CLKOUT_O, /*!< PINASSIGN11 - CLKOUT Output */
SWM_GPIO_INT_BMAT_O, /*!< PINASSIGN11 - GPIO INT BMAT Output */
} CHIP_SWM_PIN_MOVABLE_T;
#else
typedef enum CHIP_SWM_PIN_MOVABLE {
SWM_U0_TXD_O = 0x00, /*!< PINASSIGN0 - UART0 TXD Output */
SWM_U0_RXD_I = 0x01, /*!< PINASSIGN0 - UART0 RXD Input */
SWM_U0_RTS_O = 0x02, /*!< PINASSIGN0 - UART0 RTS Output */
SWM_U0_CTS_I = 0x03, /*!< PINASSIGN0 - UART0 CTS Input */
SWM_U0_SCLK_IO = 0x10, /*!< PINASSIGN1 - UART0 SCLK I/O */
SWM_U1_TXD_O = 0x11, /*!< PINASSIGN1 - UART1 TXD Output */
SWM_U1_RXD_I = 0x12, /*!< PINASSIGN1 - UART1 RXD Input */
SWM_U1_RTS_O = 0x13, /*!< PINASSIGN1 - UART1 RTS Output */
SWM_U1_CTS_I = 0x20, /*!< PINASSIGN2 - UART1 CTS Input */
SWM_U1_SCLK_IO = 0x21, /*!< PINASSIGN2 - UART1 SCLK I/O */
SWM_U2_TXD_O = 0x22, /*!< PINASSIGN2 - UART2 TXD Output */
SWM_U2_RXD_I = 0x23, /*!< PINASSIGN2 - UART2 RXD Input */
SWM_U2_RTS_O = 0x30, /*!< PINASSIGN3 - UART2 RTS Output */
SWM_U2_CTS_I = 0x31, /*!< PINASSIGN3 - UART2 CTS Input */
SWM_U2_SCLK_IO = 0x32, /*!< PINASSIGN3 - UART2 SCLK I/O */
SWM_SPI0_SCK_IO = 0x33, /*!< PINASSIGN3 - SPI0 SCK I/O */
SWM_SPI0_MOSI_IO = 0x40, /*!< PINASSIGN4 - SPI0 MOSI I/O */
SWM_SPI0_MISO_IO = 0x41, /*!< PINASSIGN4 - SPI0 MISO I/O */
SWM_SPI0_SSEL_IO = 0x42, /*!< PINASSIGN4 - SPI0 SSEL I/O */
SWM_SPI1_SCK_IO = 0x43, /*!< PINASSIGN4 - SPI1 SCK I/O */
SWM_SPI1_MOSI_IO = 0x50, /*!< PINASSIGN5 - SPI1 MOSI I/O */
SWM_SPI1_MISO_IO = 0x51, /*!< PINASSIGN5 - SPI1 MISO I/O */
SWM_SPI1_SSEL_IO = 0x52, /*!< PINASSIGN5 - SPI1 SSEL I/O */
SWM_CTIN_0_I = 0x53, /*!< PINASSIGN5 - CTIN0 Input */
SWM_CTIN_1_I = 0x60, /*!< PINASSIGN6 - CTIN1 Input */
SWM_CTIN_2_I = 0x61, /*!< PINASSIGN6 - CTIN2 Input */
SWM_CTIN_3_I = 0x62, /*!< PINASSIGN6 - CTIN3 Input */
SWM_CTOUT_0_O = 0x63, /*!< PINASSIGN6 - CTOUT0 Output */
SWM_CTOUT_1_O = 0x70, /*!< PINASSIGN7 - CTOUT1 Output */
SWM_CTOUT_2_O = 0x71, /*!< PINASSIGN7 - CTOUT2 Output */
SWM_CTOUT_3_O = 0x72, /*!< PINASSIGN7 - CTOUT3 Output */
SWM_I2C_SDA_IO = 0x73, /*!< PINASSIGN7 - I2C SDA I/O */
SWM_I2C_SCL_IO = 0x80, /*!< PINASSIGN8 - I2C SCL I/O */
SWM_ACMP_O_O = 0x81, /*!< PINASSIGN8 - I2C ACMP Output */
SWM_CLKOUT_O = 0x82, /*!< PINASSIGN8 - I2C CLKOUT Output */
SWM_GPIO_INT_BMAT_O = 0x83, /*!< PINASSIGN8 - I2C GPIO INT BMAT Output */
} CHIP_SWM_PIN_MOVABLE_T;
#endif
/**
* @brief LPC8XX Switch Matrix Fixed pins
*/
#if defined(CHIP_LPC82X)
typedef enum CHIP_SWM_PIN_FIXED {
SWM_FIXED_ACMP_I1 = 0, /*!< ACMP I1 */
SWM_FIXED_ACMP_I2 = 1, /*!< ACMP I2 */
SWM_FIXED_ACMP_I3 = 2, /*!< ACMP I3 */
SWM_FIXED_ACMP_I4 = 3, /*!< ACMP I4 */
SWM_FIXED_SWCLK = 4, /*!< SWCLK */
SWM_FIXED_SWDIO = 5, /*!< SWDIO */
SWM_FIXED_XTALIN = 6, /*!< XTALIN */
SWM_FIXED_XTALOUT = 7, /*!< XTALOUT */
SWM_FIXED_RST = 8, /*!< Reset */
SWM_FIXED_CLKIN = 9, /*!< Clock Input */
SWM_FIXED_VDDCMP = 10, /*!< VDD */
SWM_FIXED_I2C0_SDA = 11, /*!< I2C0 SDA */
SWM_FIXED_I2C0_SCL = 12, /*!< I2C0 SCL */
SWM_FIXED_ADC0 = 13, /*!< ADC0 */
SWM_FIXED_ADC1 = 14, /*!< ADC1 */
SWM_FIXED_ADC2 = 15, /*!< ADC2 */
SWM_FIXED_ADC3 = 16, /*!< ADC3 */
SWM_FIXED_ADC4 = 17, /*!< ADC4 */
SWM_FIXED_ADC5 = 18, /*!< ADC5 */
SWM_FIXED_ADC6 = 19, /*!< ADC6 */
SWM_FIXED_ADC7 = 20, /*!< ADC7 */
SWM_FIXED_ADC8 = 21, /*!< ADC8 */
SWM_FIXED_ADC9 = 22, /*!< ADC9 */
SWM_FIXED_ADC10 = 23, /*!< ADC10 */
SWM_FIXED_ADC11 = 24, /*!< ADC11 */
} CHIP_SWM_PIN_FIXED_T;
#else
typedef enum CHIP_SWM_PIN_FIXED {
SWM_FIXED_ACMP_I1 = 0, /*!< ACMP I1 */
SWM_FIXED_ACMP_I2 = 1, /*!< ACMP I2 */
SWM_FIXED_SWCLK = 2, /*!< SWCLK */
SWM_FIXED_SWDIO = 3, /*!< SWDIO */
SWM_FIXED_XTALIN = 4, /*!< XTALIN */
SWM_FIXED_XTALOUT = 5, /*!< XTALOUT */
SWM_FIXED_RST = 6, /*!< Reset */
SWM_FIXED_CLKIN = 7, /*!< Clock Input */
SWM_FIXED_VDDCMP = 8 /*!< VDD */
} CHIP_SWM_PIN_FIXED_T;
#endif
/**
* @brief Initialise the SWM module
* @return Nothing
* @note This function only enables the SWM clock.
*/
STATIC INLINE void Chip_SWM_Init(void)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
}
/**
* @brief Deinitialise the SWM module
* @return Nothing
* @note This function only disables the SWM clock.
*/
STATIC INLINE void Chip_SWM_Deinit(void)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
}
/**
* @brief Assign movable pin function to physical pin in Switch Matrix
* @param movable : Movable pin function
* @param assign : Physical pin to be assigned
* @return Nothing
*/
void Chip_SWM_MovablePinAssign(CHIP_SWM_PIN_MOVABLE_T movable, uint8_t assign);
/**
* @brief Enables or Disable Fixed Function Pin in the Switch Matrix
* @param pin : Pin to be enabled or disabled
* @param enable : True to enable the pin, False to disable the pin
* @return Nothing
*/
void Chip_SWM_FixedPinEnable(CHIP_SWM_PIN_FIXED_T pin, bool enable);
/**
* @brief Enables a Fixed Function Pin in the Switch Matrix
* @param pin : Pin to be enabled
* @return Nothing
*/
STATIC INLINE void Chip_SWM_EnableFixedPin(CHIP_SWM_PIN_FIXED_T pin)
{
LPC_SWM->PINENABLE0 &= ~((1 << (uint32_t) pin) | SWM_PINENABLE0_RESERVED);
}
/**
* @brief Disables a Fixed Function Pin in the Switch Matrix
* @param pin : Pin to be disabled
* @return Nothing
*/
STATIC INLINE void Chip_SWM_DisableFixedPin(CHIP_SWM_PIN_FIXED_T pin)
{
LPC_SWM->PINENABLE0 = (1 << (uint32_t) pin) | (LPC_SWM->PINENABLE0 & ~SWM_PINENABLE0_RESERVED);
}
/**
* @brief Tests whether a fixed pin is enabled or disabled in the Switch Matrix
* @param pin : The pin to test whether it is enabled or disabled
* @return True if the pin is enabled, False if disabled
*/
STATIC INLINE bool Chip_SWM_IsEnabled(CHIP_SWM_PIN_FIXED_T pin)
{
return (bool) ((LPC_SWM->PINENABLE0 & (1 << (uint32_t) pin)) == 0);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __IOCON_8XX_H_ */

View File

@ -0,0 +1,216 @@
/*
* @brief Common types used in LPC functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __LPC_TYPES_H_
#define __LPC_TYPES_H_
#include <stdint.h>
#include <stdbool.h>
/** @defgroup LPC_Types CHIP: LPC Common Types
* @ingroup CHIP_Common
* @{
*/
/** @defgroup LPC_Types_Public_Types LPC Public Types
* @{
*/
/**
* @brief Boolean Type definition
*/
typedef enum {FALSE = 0, TRUE = !FALSE} Bool;
/**
* @brief Boolean Type definition
*/
#if !defined(__cplusplus)
// typedef enum {false = 0, true = !false} bool;
#endif
/**
* @brief Flag Status and Interrupt Flag Status type definition
*/
typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState;
#define PARAM_SETSTATE(State) ((State == RESET) || (State == SET))
/**
* @brief Functional State Definition
*/
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define PARAM_FUNCTIONALSTATE(State) ((State == DISABLE) || (State == ENABLE))
/**
* @ Status type definition
*/
typedef enum {ERROR = 0, SUCCESS = !ERROR} Status;
/**
* Read/Write transfer type mode (Block or non-block)
*/
typedef enum {
NONE_BLOCKING = 0, /**< None Blocking type */
BLOCKING, /**< Blocking type */
} TRANSFER_BLOCK_T;
/** Pointer to Function returning Void (any number of parameters) */
typedef void (*PFV)();
/** Pointer to Function returning int32_t (any number of parameters) */
typedef int32_t (*PFI)();
/**
* @}
*/
/** @defgroup LPC_Types_Public_Macros LPC Public Macros
* @{
*/
/* _BIT(n) sets the bit at position "n"
* _BIT(n) is intended to be used in "OR" and "AND" expressions:
* e.g., "(_BIT(3) | _BIT(7))".
*/
#undef _BIT
/* Set bit macro */
#define _BIT(n) (1 << (n))
/* _SBF(f,v) sets the bit field starting at position "f" to value "v".
* _SBF(f,v) is intended to be used in "OR" and "AND" expressions:
* e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)"
*/
#undef _SBF
/* Set bit field macro */
#define _SBF(f, v) ((v) << (f))
/* _BITMASK constructs a symbol with 'field_width' least significant
* bits set.
* e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF
* The symbol is intended to be used to limit the bit field width
* thusly:
* <a_register> = (any_expression) & _BITMASK(x), where 0 < x <= 32.
* If "any_expression" results in a value that is larger than can be
* contained in 'x' bits, the bits above 'x - 1' are masked off. When
* used with the _SBF example above, the example would be written:
* a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16))
* This ensures that the value written to a_reg is no wider than
* 16 bits, and makes the code easier to read and understand.
*/
#undef _BITMASK
/* Bitmask creation macro */
#define _BITMASK(field_width) ( _BIT(field_width) - 1)
/* NULL pointer */
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Number of elements in an array */
#define NELEMENTS(array) (sizeof(array) / sizeof(array[0]))
/* Static data/function define */
#define STATIC static
/* External data/function define */
#define EXTERN extern
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/**
* @}
*/
/* Old Type Definition compatibility */
/** @addtogroup LPC_Types_Public_Types
* @{
*/
/** LPC type for character type */
typedef char CHAR;
/** LPC type for 8 bit unsigned value */
typedef uint8_t UNS_8;
/** LPC type for 8 bit signed value */
typedef int8_t INT_8;
/** LPC type for 16 bit unsigned value */
typedef uint16_t UNS_16;
/** LPC type for 16 bit signed value */
typedef int16_t INT_16;
/** LPC type for 32 bit unsigned value */
typedef uint32_t UNS_32;
/** LPC type for 32 bit signed value */
typedef int32_t INT_32;
/** LPC type for 64 bit signed value */
typedef int64_t INT_64;
/** LPC type for 64 bit unsigned value */
typedef uint64_t UNS_64;
#ifdef __CODE_RED
#define BOOL_32 bool
#define BOOL_16 bool
#define BOOL_8 bool
#else
/** 32 bit boolean type */
typedef bool BOOL_32;
/** 16 bit boolean type */
typedef bool BOOL_16;
/** 8 bit boolean type */
typedef bool BOOL_8;
#endif
#ifdef __CC_ARM
#define INLINE __inline
#else
#define INLINE inline
#endif
/**
* @}
*/
/**
* @}
*/
#endif /* __LPC_TYPES_H_ */

View File

@ -0,0 +1,107 @@
/*
* @brief LPC8xx System & Control driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#define _CHIP_COMMON_
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* PDSLEEPCFG register mask */
#define PDSLEEPWRMASK (0x0000FFB7)
#define PDSLEEPDATMASK (0x00000048)
#if defined(CHIP_LPC82X)
/* PDWAKECFG and PDRUNCFG register masks */
#define PDWAKEUPWRMASK (0x00006D00)
#define PDWAKEUPDATMASK (0x000080FF)
#else
/* PDWAKECFG and PDRUNCFG register masks */
#define PDWAKEUPWRMASK (0x00006D10)
#define PDWAKEUPDATMASK (0x000080EF)
#endif
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Setup deep sleep behaviour for power down */
void Chip_SYSCTL_SetDeepSleepPD(uint32_t sleepmask)
{
/* Update new value */
LPC_SYSCTL->PDSLEEPCFG = PDSLEEPWRMASK | (sleepmask & PDSLEEPDATMASK);
}
/* Setup wakeup behaviour from deep sleep */
void Chip_SYSCTL_SetWakeup(uint32_t wakeupmask)
{
/* Update new value */
LPC_SYSCTL->PDAWAKECFG = PDWAKEUPWRMASK | (wakeupmask & PDWAKEUPDATMASK);
}
/* Power down one or more blocks or peripherals */
void Chip_SYSCTL_PowerDown(uint32_t powerdownmask)
{
uint32_t pdrun;
/* Get current power states */
pdrun = LPC_SYSCTL->PDRUNCFG & PDWAKEUPDATMASK;
/* Disable peripheral states by setting high */
pdrun |= (powerdownmask & PDWAKEUPDATMASK);
/* Update power states with required register bits */
LPC_SYSCTL->PDRUNCFG = (PDWAKEUPWRMASK | pdrun);
}
/* Power up one or more blocks or peripherals */
void Chip_SYSCTL_PowerUp(uint32_t powerupmask)
{
uint32_t pdrun;
/* Get current power states */
pdrun = LPC_SYSCTL->PDRUNCFG & PDWAKEUPDATMASK;
/* Enable peripheral states by setting low */
pdrun &= ~(powerupmask & PDWAKEUPDATMASK);
/* Update power states with required register bits */
LPC_SYSCTL->PDRUNCFG = (PDWAKEUPWRMASK | pdrun);
}

View File

@ -0,0 +1,573 @@
/*
* @brief LPC8xx System & Control driver inclusion file
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SYSCTL_8XX_H_
#define __SYSCTL_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup SYSCTL_8XX CHIP: LPC8xx System and Control Driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* System reset status values
*/
#define SYSCTL_RST_POR (1 << 0) /*!< POR reset status */
#define SYSCTL_RST_EXTRST (1 << 1) /*!< External reset status */
#define SYSCTL_RST_WDT (1 << 2) /*!< Watchdog reset status */
#define SYSCTL_RST_BOD (1 << 3) /*!< Brown-out detect reset status */
#define SYSCTL_RST_SYSRST (1 << 4) /*!< software system reset status */
/**
* Peripheral interrupt wakeup events values
*/
#define SYSCTL_WAKEUP_SPI0TINT (1 << 0) /*!< SPI0 interrupt wake-up */
#define SYSCTL_WAKEUP_SPI1INT (1 << 1) /*!< SPI0 interrupt wake-up */
#define SYSCTL_WAKEUP_USART0INT (1 << 3) /*!< USART0 interrupt wake-up */
#define SYSCTL_WAKEUP_USART1INT (1 << 4) /*!< USART1 interrupt wake-up */
#define SYSCTL_WAKEUP_USART2INT (1 << 5) /*!< USART2 interrupt wake-up */
#define SYSCTL_WAKEUP_I2C0INT (1 << 8) /*!< I2C0 interrupt wake-up */
#define SYSCTL_WAKEUP_I2C1INT (1 << 7) /*!< I2C1 interrupt wake-up [Available only on LPC82X] */
#define SYSCTL_WAKEUP_I2C2INT (1 << 21) /*!< I2C2 interrupt wake-up [Available only on LPC82X] */
#define SYSCTL_WAKEUP_I2C3INT (1 << 22) /*!< I2C3 interrupt wake-up [Available only on LPC82X] */
#define SYSCTL_WAKEUP_WWDTINT (1 << 12) /*!< WWDT interrupt wake-up */
#define SYSCTL_WAKEUP_BODINT (1 << 13) /*!< Brown Out Detect (BOD) interrupt wake-up */
#define SYSCTL_WAKEUP_WKTINT (1 << 15) /*!< Self wake-up timer interrupt wake-up */
#define SYSCTL_WAKEUP_I2CINT SYSCTL_WAKEUP_I2C0INT /*!< Same as #SYSCTL_WAKEUP_I2CINT */
/**
* Deep sleep setup values
*/
#define SYSCTL_DEEPSLP_BOD_PD (1 << 3) /*!< BOD power-down control in Deep-sleep mode, powered down */
#define SYSCTL_DEEPSLP_WDTOSC_PD (1 << 6) /*!< Watchdog oscillator power control in Deep-sleep, powered down */
/**
* Deep sleep to wakeup and power state setup values
*/
#define SYSCTL_SLPWAKE_IRCOUT_PD (1 << 0) /*!< IRC oscillator output wake-up configuration */
#define SYSCTL_SLPWAKE_IRC_PD (1 << 1) /*!< IRC oscillator power-down wake-up configuration */
#define SYSCTL_SLPWAKE_FLASH_PD (1 << 2) /*!< Flash wake-up configuration */
#define SYSCTL_SLPWAKE_BOD_PD (1 << 3) /*!< BOD wake-up configuration */
#define SYSCTL_SLPWAKE_ADC_PD (1 << 4) /*!< ADC wake-up configuration [Available only on LPC82x] */
#define SYSCTL_SLPWAKE_SYSOSC_PD (1 << 5) /*!< System oscillator wake-up configuration */
#define SYSCTL_SLPWAKE_WDTOSC_PD (1 << 6) /*!< Watchdog oscillator wake-up configuration */
#define SYSCTL_SLPWAKE_SYSPLL_PD (1 << 7) /*!< System PLL wake-up configuration */
#define SYSCTL_SLPWAKE_ACMP_PD (1 << 15) /*!< Analog comparator wake-up configuration */
/**
* Non-Maskable Interrupt Enable/Disable value
*/
#define SYSCTL_NMISRC_ENABLE ((uint32_t) 1 << 31) /*!< Enable the Non-Maskable Interrupt (NMI) source */
/**
* @brief LPC8XX System Control and Clock register block structure
*/
typedef struct {
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 System memory remap (R/W) */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 System PLL control (R/W) */
__IO uint32_t SYSPLLSTAT; /*!< Offset: 0x00C System PLL status (R/W ) */
uint32_t RESERVED0[4];
__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 System oscillator control (R/W) */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 Watchdog oscillator control (R/W) */
__IO uint32_t IRCCTRL; /*!< Offset: 0x028 IRC Control Register (Available only in LPC82X) */
uint32_t RESERVED1[1];
__IO uint32_t SYSRSTSTAT; /*!< Offset: 0x030 System reset status Register (R/W ) */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 System PLL clock source select (R/W) */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 System PLL clock source update enable (R/W) */
uint32_t RESERVED3[10];
__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 Main clock source select (R/W) */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 Main clock source update enable (R/W) */
__IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 System AHB clock divider (R/W) */
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */
uint32_t RESERVED5[4];
__IO uint32_t UARTCLKDIV; /*!< Offset: 0x094 UART clock divider (R/W) */
uint32_t RESERVED6[18];
__IO uint32_t CLKOUTSEL; /*!< Offset: 0x0E0 CLKOUT clock source select (R/W) */
__IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 CLKOUT clock source update enable (R/W) */
__IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 CLKOUT clock divider (R/W) */
uint32_t RESERVED7;
__IO uint32_t UARTFRGDIV; /*!< Offset: 0x0F0 UART fractional divider SUB(R/W) */
__IO uint32_t UARTFRGMULT; /*!< Offset: 0x0F4 UART fractional divider ADD(R/W) */
uint32_t RESERVED8[1];
__IO uint32_t EXTTRACECMD; /*!< Offset: 0x0FC External trace buffer command register */
__IO uint32_t PIOPORCAP0; /*!< Offset: 0x100 POR captured PIO status 0 (R/ ) */
uint32_t RESERVED9[12];
__IO uint32_t IOCONCLKDIV[7]; /*!< Offset: 0x134 Peripheral clock x to the IOCON block for programmable glitch filter */
__IO uint32_t BODCTRL; /*!< Offset: 0x150 BOD control (R/W) */
__IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 System tick counter calibration (R/W) */
uint32_t RESERVED10[6];
__IO uint32_t IRQLATENCY; /*!< Offset: 0x170 IRQ delay */
__IO uint32_t NMISRC; /*!< Offset: 0x174 NMI Source Control */
__IO uint32_t PINTSEL[8]; /*!< Offset: 0x178 GPIO Pin Interrupt Select register 0 */
uint32_t RESERVED11[27];
__IO uint32_t STARTERP0; /*!< Offset: 0x204 Start logic signal enable Register 0 (R/W) */
uint32_t RESERVED12[3];
__IO uint32_t STARTERP1; /*!< Offset: 0x214 Start logic signal enable Register 0 (R/W) */
uint32_t RESERVED13[6];
__IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 Power-down states in Deep-sleep mode (R/W) */
__IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 Power-down states after wake-up (R/W) */
__IO uint32_t PDRUNCFG; /*!< Offset: 0x238 Power-down configuration Register (R/W) */
uint32_t RESERVED14[111];
__I uint32_t DEVICEID; /*!< Offset: 0x3F8 Device ID (R/ ) */
} LPC_SYSCTL_T;
/**
* @brief IOCON Perpipheral Clock divider selction for input filter
* sampling clock
*/
typedef enum CHIP_PIN_CLKDIV {
IOCONCLKDIV0 = 0, /*!< Clock divider 0 */
IOCONCLKDIV1, /*!< Clock divider 1 */
IOCONCLKDIV2, /*!< Clock divider 2 */
IOCONCLKDIV3, /*!< Clock divider 3 */
IOCONCLKDIV4, /*!< Clock divider 4 */
IOCONCLKDIV5, /*!< Clock divider 5 */
IOCONCLKDIV6, /*!< Clock divider 6 */
IOCONCLK_MAX = IOCONCLKDIV6 /*!< Top value used to reverse the dividers */
} CHIP_PIN_CLKDIV_T;
/* Reserved bits masks for registers */
#define SYSCTL_SYSMEMREMAP_RESERVED (~3)
#define SYSCTL_SYSPLLCTRL_RESERVED (~0x7f)
#define SYSCTL_SYSPLLSTAT_RESERVED (~1)
#define SYSCTL_SYSOSCCTRL_RESERVED (~3)
#define SYSCTL_WDTOSCCTRL_RESERVED (~0x1ff)
#define SYSCTL_SYSRSTSTAT_RESERVED (~0x1f)
#define SYSCTL_SYSPLLCLKSEL_RESERVED (~3)
#define SYSCTL_SYSPLLCLKUEN_RESERVED (~1)
#define SYSCTL_MAINCLKSEL_RESERVED (~3)
#define SYSCTL_MAINCLKUEN_RESERVED (~1)
#define SYSCTL_SYSAHBCLKDIV_RESERVED (~0xff)
#define SYSCTL_UARTCLKDIV_RESERVED (~0xff)
#define SYSCTL_CLKOUTSEL_RESERVED (~3)
#define SYSCTL_CLKOUTUEN_RESERVED (~1)
#define SYSCTL_CLKOUTDIV_RESERVED (~0xff)
#define SYSCTL_UARTFRGDIV_RESERVED (~0xff)
#define SYSCTL_UARTFRGMULT_RESERVED (~0xff)
#define SYSCTL_EXTTRACECMD_RESERVED (~3)
#define SYSCTL_IOCONCLKDIV_RESERVED (~0xff)
#define SYSCTL_BODCTRL_RESERVED (~0x1f)
#define SYSCTL_SYSTCKCAL_RESERVED 0xfc000000
#define SYSCTL_IRQLATENCY_RESERVED (~0xff)
#define SYSCTL_NMISRC_RESERVED (~(0x1f|(1u<<31)))
#define SYSCTL_PINTSEL_RESERVED (~0x3f)
#define SYSCTL_STARTERP0_RESERVED (~0xff)
#if defined(CHIP_LPC82X)
#define SYSCTL_PRESETCTRL_RESERVED 0xfffe2000
#define SYSCTL_SYSAHBCLKCTRL_RESERVED 0xda100000
#define SYSCTL_PIOPORCAP0_RESERVED 0xfffc0000
#define SYSCTL_STARTERP1_RESERVED ((1<<2)|(1<<6)|(7<<9)|(1<<14)|0xff9f0000)
#else
#define SYSCTL_PRESETCTRL_RESERVED 0xffffe000
#define SYSCTL_SYSAHBCLKCTRL_RESERVED 0xfff00000
#define SYSCTL_PIOPORCAP0_RESERVED 0xffffc000
#define SYSCTL_STARTERP1_RESERVED ((1<<2)|(3<<6)|(7<<9)|(1<<14)|(0x1f<<16)|0xff800000)
#endif
/* The following have reserved bits, but they are specially handled elsewhere. */
/* #define SYSCTL_PDSLEEPCFG_RESERVED (~(1<<3)|(3<<4)|(1<<6)) */
/* #define SYSCTL_PDAWAKECFG_RESERVED */
/* #define SYSCTL_PDRUNCFG_RESERVED */
/**
* System memory remap modes used to remap interrupt vectors
*/
typedef enum CHIP_SYSCTL_BOOT_MODE_REMAP {
REMAP_BOOT_LOADER_MODE, /*!< Interrupt vectors are re-mapped to Boot ROM */
REMAP_USER_RAM_MODE, /*!< Interrupt vectors are re-mapped to user Static RAM */
REMAP_USER_FLASH_MODE /*!< Interrupt vectors are not re-mapped and reside in Flash */
} CHIP_SYSCTL_BOOT_MODE_REMAP_T;
/**
* Peripheral reset identifiers
*/
typedef enum {
RESET_SPI0, /*!< SPI0 reset control */
RESET_SPI1, /*!< SPI1 reset control */
RESET_UARTFBRG, /*!< UART fractional baud rate generator reset control */
RESET_USART0, /*!< USART0 reset control */
RESET_USART1, /*!< USART1 reset control */
RESET_USART2, /*!< USART2 reset control */
RESET_I2C0, /*!< I2C0 reset control */
RESET_MRT, /*!< MRT reset control */
RESET_SCT, /*!< SCT reset control */
RESET_WKT, /*!< Self wake-up timer (WKT) control */
RESET_GPIO, /*!< GPIO reset control */
RESET_FLASH, /*!< FLASH reset control */
RESET_ACMP, /*!< ACMP reset control */
RESET_I2C1 = 14, /*!< I2C1 reset control [Available only in LPC82x] */
RESET_I2C2, /*!< I2C2 reset control [Available only in LPC82x] */
RESET_I2C3, /*!< I2C3 reset control [Available only in LPC82x] */
} CHIP_SYSCTL_PERIPH_RESET_T;
/* Reset Alias */
#define RESET_I2C RESET_I2C0
/**
* Brown-out detector reset level
*/
typedef enum CHIP_SYSCTL_BODRSTLVL {
SYSCTL_BODRSTLVL_0, /*!< Brown-out reset at 1.46 ~ 1.63v */
SYSCTL_BODRSTLVL_1, /*!< Brown-out reset at 2.06v ~ 2.15v */
SYSCTL_BODRSTLVL_2, /*!< Brown-out reset at 2.35v ~ 2.43v */
SYSCTL_BODRSTLVL_3, /*!< Brown-out reset at 2.63v ~ 2.71v */
} CHIP_SYSCTL_BODRSTLVL_T;
/**
* Brown-out detector interrupt level
*/
typedef enum CHIP_SYSCTL_BODRINTVAL {
SYSCTL_BODINTVAL_LVL0, /* Brown-out interrupt at 1.65 ~ 1.80v */
SYSCTL_BODINTVAL_LVL1, /* Brown-out interrupt at 2.22v ~ 2.35v*/
SYSCTL_BODINTVAL_LVL2, /* Brown-out interrupt at 2.52v ~ 2.66v */
SYSCTL_BODINTVAL_LVL3, /* Brown-out interrupt at 2.80v ~ 2.90v */
} CHIP_SYSCTL_BODRINTVAL_T;
/**
* @brief Re-map interrupt vectors
* @param remap : system memory map value
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_Map(CHIP_SYSCTL_BOOT_MODE_REMAP_T remap)
{
LPC_SYSCTL->SYSMEMREMAP = (uint32_t) remap;
}
/**
* @brief Assert reset for a peripheral
* @param periph : Peripheral to assert reset for
* @return Nothing
* @note The peripheral will stay in reset until reset is de-asserted. Call
* Chip_SYSCTL_DeassertPeriphReset() to de-assert the reset
*/
STATIC INLINE void Chip_SYSCTL_AssertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph)
{
LPC_SYSCTL->PRESETCTRL &= ~((1 << (uint32_t) periph) | SYSCTL_PRESETCTRL_RESERVED);
}
/**
* @brief De-assert reset for a peripheral
* @param periph : Peripheral to de-assert reset for
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_DeassertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph)
{
LPC_SYSCTL->PRESETCTRL = (1 << (uint32_t) periph) | (LPC_SYSCTL->PRESETCTRL & ~SYSCTL_PRESETCTRL_RESERVED);
}
/**
* @brief Resets a peripheral
* @param periph : Peripheral to reset
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_PeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph)
{
Chip_SYSCTL_AssertPeriphReset(periph);
Chip_SYSCTL_DeassertPeriphReset(periph);
}
/**
* @brief Get system reset status
* @return An Or'ed value of SYSCTL_RST_*
* @note This function returns the detected reset source(s).
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetSystemRSTStatus(void)
{
return LPC_SYSCTL->SYSRSTSTAT & ~SYSCTL_SYSRSTSTAT_RESERVED;
}
/**
* @brief Clear system reset status
* @param reset : An Or'ed value of SYSCTL_RST_* status to clear
* @return Nothing
* @note This function clears the specified reset source(s).
*/
STATIC INLINE void Chip_SYSCTL_ClearSystemRSTStatus(uint32_t reset)
{
LPC_SYSCTL->SYSRSTSTAT = reset;
}
/**
* @brief Read POR captured PIO status
* @return captured POR PIO status
* @note Some devices only support index 0.
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetPORPIOStatus(void)
{
return LPC_SYSCTL->PIOPORCAP0 & ~SYSCTL_PIOPORCAP0_RESERVED;
}
/**
* @brief Set brown-out detection interrupt and reset levels
* @param rstlvl : Brown-out detector reset level
* @param intlvl : Brown-out interrupt level
* @return Nothing
* @note Brown-out detection reset will be disabled upon exiting this function.
* Use Chip_SYSCTL_EnableBODReset() to re-enable
*/
STATIC INLINE void Chip_SYSCTL_SetBODLevels(CHIP_SYSCTL_BODRSTLVL_T rstlvl,
CHIP_SYSCTL_BODRINTVAL_T intlvl)
{
LPC_SYSCTL->BODCTRL = ((uint32_t) rstlvl) | (((uint32_t) intlvl) << 2);
}
/**
* @brief Enable brown-out detection reset
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_EnableBODReset(void)
{
LPC_SYSCTL->BODCTRL = (1 << 4) | (LPC_SYSCTL->BODCTRL & ~SYSCTL_BODCTRL_RESERVED);
}
/**
* @brief Disable brown-out detection reset
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_DisableBODReset(void)
{
LPC_SYSCTL->BODCTRL &= ~((1 << 4) | SYSCTL_BODCTRL_RESERVED);
}
/**
* @brief Set System tick timer calibration value
* @param sysCalVal : System tick timer calibration value
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_SetSYSTCKCAL(uint32_t sysCalVal)
{
LPC_SYSCTL->SYSTCKCAL = sysCalVal;
}
/**
* @brief Set System IRQ latency
* @param latency : Latency in clock ticks
* @return Nothing
* @note Sets the IRQ latency, a value between 0 and 255 clocks. Lower
* values allow better latency
*/
STATIC INLINE void Chip_SYSCTL_SetIRQLatency(uint32_t latency)
{
LPC_SYSCTL->IRQLATENCY = latency;
}
/**
* @brief Get System IRQ latency value
* @return IRQ Latency in clock ticks
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetIRQLatency(void)
{
return LPC_SYSCTL->IRQLATENCY & ~SYSCTL_IRQLATENCY_RESERVED;
}
/**
* @brief Set source for non-maskable interrupt (NMI)
* @param intsrc : IRQ number to assign to the NMI
* @return Nothing
* @note The NMI source will be disabled upon exiting this function. Use the
* Chip_SYSCTL_EnableNMISource() function to enable the NMI source
*/
STATIC INLINE void Chip_SYSCTL_SetNMISource(uint32_t intsrc)
{
/* Disable NMI first */
LPC_SYSCTL->NMISRC &= ~(SYSCTL_NMISRC_ENABLE | SYSCTL_NMISRC_RESERVED);
/* Set new NMI source. */
LPC_SYSCTL->NMISRC = intsrc;
}
/**
* @brief Enable interrupt used for NMI source
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_EnableNMISource(void)
{
LPC_SYSCTL->NMISRC = SYSCTL_NMISRC_ENABLE | (LPC_SYSCTL->NMISRC & ~SYSCTL_NMISRC_RESERVED);
}
/**
* @brief Disable interrupt used for NMI source
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_DisableNMISource(void)
{
LPC_SYSCTL->NMISRC &= ~(SYSCTL_NMISRC_ENABLE | SYSCTL_NMISRC_RESERVED);
}
/**
* @brief Setup a pin source for the pin interrupts (0-7)
* @param intno : IRQ number
* @param pin : pin number (see comments)
* @return Nothing
* @note For each pin (0-7) that supports an interrupt, the pin number is assigned
* to that interrupt with this function. Values 0-17 map to pins PIO0-0 to
* PIO0-17 (For LPC82X Values from 0-28 could be used for PIO0-28).
*/
STATIC INLINE void Chip_SYSCTL_SetPinInterrupt(uint32_t intIndex, uint32_t pinNum)
{
LPC_SYSCTL->PINTSEL[intIndex] = (uint32_t) pinNum;
}
/**
* @brief Enables a pin's (PINT) wakeup logic
* @param pin : pin number
* @return Nothing
* @note Different devices support different pins, see the user manual
* for supported pins
*/
STATIC INLINE void Chip_SYSCTL_EnablePINTWakeup(uint32_t pin)
{
LPC_SYSCTL->STARTERP0 = (1 << pin) | (LPC_SYSCTL->STARTERP0 & ~SYSCTL_STARTERP0_RESERVED);
}
/**
* @brief Disables a pin's (PINT) wakeup logic
* @param pin : pin number
* @return Nothing
* @note Different devices support different pins, see the user manual for supported pins.
*/
STATIC INLINE void Chip_SYSCTL_DisablePINTWakeup(uint32_t pin)
{
LPC_SYSCTL->STARTERP0 &= ~((1 << pin) | SYSCTL_STARTERP0_RESERVED);
}
/**
* @brief Enables peripheral's wakeup logic
* @param periphmask : OR'ed values of SYSCTL_WAKEUP_* for wakeup
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_EnablePeriphWakeup(uint32_t periphmask)
{
LPC_SYSCTL->STARTERP1 = periphmask | (LPC_SYSCTL->STARTERP0 & ~SYSCTL_STARTERP0_RESERVED);
}
/**
* @brief Disables peripheral's wakeup logic
* @param periphmask : OR'ed values of SYSCTL_WAKEUP_* for wakeup
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_DisablePeriphWakeup(uint32_t periphmask)
{
LPC_SYSCTL->STARTERP1 &= ~(periphmask | SYSCTL_STARTERP1_RESERVED);
}
/**
* @brief Returns current deep sleep mask
* @return OR'ed values of SYSCTL_DEEPSLP_* values
* @note A high bit indicates the peripheral will power down on deep sleep.
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetDeepSleepPD(void)
{
return LPC_SYSCTL->PDSLEEPCFG;
}
/**
* @brief Return current wakup mask
* @return OR'ed values of SYSCTL_SLPWAKE_* values
* @note A high state indicates the peripehral will powerup on wakeup.
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetWakeup(void)
{
return LPC_SYSCTL->PDAWAKECFG;
}
/**
* @brief Power up one or more blocks or peripherals
* @return OR'ed values of SYSCTL_SLPWAKE_* values
* @note A high state indicates the peripheral is powered down.
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetPowerStates(void)
{
return LPC_SYSCTL->PDRUNCFG;
}
/**
* @brief Return the device ID
* @return Device ID
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetDeviceID(void)
{
return LPC_SYSCTL->DEVICEID;
}
/**
* @brief Setup deep sleep behaviour for power down
* @param sleepmask : OR'ed values of SYSCTL_DEEPSLP_* values (high to powerdown on deepsleep)
* @return Nothing
* @note This must be setup prior to using deep sleep. See the user manual
* *(PDSLEEPCFG register) for more info on setting this up. This function selects
* which peripherals are powered down on deep sleep.
* This function should only be called once with all options for power-down
* in that call
*/
void Chip_SYSCTL_SetDeepSleepPD(uint32_t sleepmask);
/**
* @brief Setup wakeup behaviour from deep sleep
* @param wakeupmask : OR'ed values of SYSCTL_SLPWAKE_* values (high is powered down)
* @return Nothing
* @note This must be setup prior to using deep sleep. See the user manual
* *(PDWAKECFG register) for more info on setting this up. This function selects
* which peripherals are powered up on exit from deep sleep.
* This function should only be called once with all options for wakeup
* in that call
*/
void Chip_SYSCTL_SetWakeup(uint32_t wakeupmask);
/**
* @brief Power down one or more blocks or peripherals
* @param powerdownmask : OR'ed values of SYSCTL_SLPWAKE_* values
* @return Nothing
*/
void Chip_SYSCTL_PowerDown(uint32_t powerdownmask);
/**
* @brief Power up one or more blocks or peripherals
* @param powerupmask : OR'ed values of SYSCTL_SLPWAKE_* values
* @return Nothing
*/
void Chip_SYSCTL_PowerUp(uint32_t powerupmask);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SYSCTL_8XX_H_ */

View File

@ -0,0 +1,115 @@
/*
* @brief LPC8xx Chip specific SystemInit
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#define _CHIP_COMMON_
#include "board_lpc.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
#define CONFIG_MAIN_FREQ 60000000
#define CONFIG_SYS_FREQ MAX_CLOCK_FREQ
/*****************************************************************************
* Public functions
****************************************************************************/
/* Setup system clocking */
void Chip_SetupXtalClocking(void)
{
/* EXT oscillator < 15MHz */
Chip_Clock_SetPLLBypass(false, false);
/* Turn on the SYSOSC by clearing the power down bit */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_SYSOSC_PD);
/* Select the PLL input to the external oscillator */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_SYSOSC);
/* Setup FLASH access to 2 clocks (up to 30MHz) */
Chip_FMC_SetFLASHAccess(FLASHTIM_30MHZ_CPU);
/* Power down PLL to change the PLL divider ratio */
Chip_SYSCTL_PowerDown(SYSCTL_SLPWAKE_SYSPLL_PD);
/* Configure the PLL M and P dividers */
/* Setup PLL for main oscillator rate ((FCLKIN = 12MHz) * 5)/2 = 30MHz */
Chip_Clock_SetupSystemPLL(4, 1);
/* Turn on the PLL by clearing the power down bit */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_SYSPLL_PD);
/* Enable the clock to the Switch Matrix */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
/* Wait for PLL to lock */
while (!Chip_Clock_IsSystemPLLLocked()) {}
Chip_Clock_SetSysClockDiv(2);
/* Set main clock source to the system PLL. This will drive 24MHz
for the main clock and 24MHz for the system clock */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
}
/* Set up and initialize hardware prior to call to main */
void Chip_SetupIrcClocking(void)
{
Chip_IRC_SetFreq(CONFIG_MAIN_FREQ, CONFIG_SYS_FREQ);
}
/* Set up and initialize hardware prior to call to main */
/* 在main()函数之前调用此函数做基本的初始化工作 */
void SystemInit(void)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
#ifdef USE_IRC_AS_ROOT_CLOCK
/* Use 12MHz IRC as clock source */
Chip_SetupIrcClocking();
#else
/* Use Xtal or external clock_in as clock source*/
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_EnableFixedPin(SWM_FIXED_XTALIN);
Chip_SWM_EnableFixedPin(SWM_FIXED_XTALOUT);
// Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO8, PIN_MODE_INACTIVE);
Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO9, PIN_MODE_INACTIVE);
Chip_SetupXtalClocking();
#endif
}

View File

@ -0,0 +1,188 @@
/**************************************************
*
* Part one of the system initialization code, contains low-level
* initialization, plain thumb variant.
*
* Copyright 2009 IAR Systems. All rights reserved.
*
* $Revision: 33183 $
*
**************************************************/
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
EXTERN SystemInit
EXTERN IRC_Only_SystemInit
PUBLIC __vector_table
PUBLIC __vector_table_0x1c
DATA
__vector_table
DCD sfe(CSTACK) ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
__vector_table_0x1c
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD SPI0_IRQHandler ; SPI0 controller
DCD SPI1_IRQHandler ; SPI1 controller
DCD 0 ; Reserved
DCD UART0_IRQHandler ; UART0
DCD UART1_IRQHandler ; UART1
DCD UART2_IRQHandler ; UART2
DCD 0 ; Reserved
DCD I2C1_IRQHandler ; I2C1
DCD I2C0_IRQHandler ; I2C0 controller
DCD SCT_IRQHandler ; Smart Counter Timer
DCD MRT_IRQHandler ; Multi-Rate Timer
DCD CMP_IRQHandler ; Comparator
DCD WDT_IRQHandler ; PIO1 (0:11)
DCD BOD_IRQHandler ; Brown Out Detect
DCD FLASH_IRQHandler ; Flash interrupt
DCD WKT_IRQHandler ; Wakeup timer
DCD ADC_SEQA_IRQHandler ; ADC sequence A completeion
DCD ADC_SEQB_IRQHandler ; ADC sequence B completeion
DCD ADC_THCMP_IRQHandler ; ADC threshold compare
DCD ADC_OVR_IRQHandler ; ADC overrun
DCD DMA_IRQHandler ; DMA
DCD I2C2_IRQHandler ; I2C2
DCD I2C3_IRQHandler ; I2C3
DCD 0 ; Reserved
DCD PININT0_IRQHandler ; PIO INT0
DCD PININT1_IRQHandler ; PIO INT1
DCD PININT2_IRQHandler ; PIO INT2
DCD PININT3_IRQHandler ; PIO INT3
DCD PININT4_IRQHandler ; PIO INT4
DCD PININT5_IRQHandler ; PIO INT5
DCD PININT6_IRQHandler ; PIO INT6
DCD PININT7_IRQHandler ; PIO INT7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
SECTION .text:CODE:REORDER:NOROOT(1)
PUBWEAK NMI_Handler
PUBWEAK HardFault_Handler
PUBWEAK SVC_Handler
PUBWEAK DebugMon_Handler
PUBWEAK PendSV_Handler
PUBWEAK SysTick_Handler
PUBWEAK SPI0_IRQHandler
PUBWEAK SPI1_IRQHandler
PUBWEAK UART0_IRQHandler
PUBWEAK UART1_IRQHandler
PUBWEAK UART2_IRQHandler
PUBWEAK I2C1_IRQHandler
PUBWEAK I2C0_IRQHandler
PUBWEAK SCT_IRQHandler
PUBWEAK MRT_IRQHandler
PUBWEAK CMP_IRQHandler
PUBWEAK WDT_IRQHandler
PUBWEAK BOD_IRQHandler
PUBWEAK FLASH_IRQHandler
PUBWEAK WKT_IRQHandler
PUBWEAK ADC_SEQA_IRQHandler
PUBWEAK ADC_SEQB_IRQHandler
PUBWEAK ADC_THCMP_IRQHandler
PUBWEAK ADC_OVR_IRQHandler
PUBWEAK DMA_IRQHandler
PUBWEAK I2C2_IRQHandler
PUBWEAK I2C3_IRQHandler
PUBWEAK PININT0_IRQHandler
PUBWEAK PININT1_IRQHandler
PUBWEAK PININT2_IRQHandler
PUBWEAK PININT3_IRQHandler
PUBWEAK PININT4_IRQHandler
PUBWEAK PININT5_IRQHandler
PUBWEAK PININT6_IRQHandler
PUBWEAK PININT7_IRQHandler
NMI_Handler:
HardFault_Handler:
SVC_Handler:
DebugMon_Handler:
PendSV_Handler:
SysTick_Handler:
SPI0_IRQHandler:
SPI1_IRQHandler:
UART0_IRQHandler:
UART1_IRQHandler:
UART2_IRQHandler:
I2C1_IRQHandler:
I2C0_IRQHandler:
SCT_IRQHandler:
MRT_IRQHandler:
CMP_IRQHandler:
WDT_IRQHandler:
BOD_IRQHandler:
FLASH_IRQHandler:
WKT_IRQHandler:
ADC_SEQA_IRQHandler:
ADC_SEQB_IRQHandler:
ADC_THCMP_IRQHandler:
ADC_OVR_IRQHandler:
DMA_IRQHandler:
I2C2_IRQHandler:
I2C3_IRQHandler:
PININT0_IRQHandler:
PININT1_IRQHandler:
PININT2_IRQHandler:
PININT3_IRQHandler:
PININT4_IRQHandler:
PININT5_IRQHandler:
PININT6_IRQHandler:
PININT7_IRQHandler:
Default_Handler:
B Default_Handler
END

View File

@ -0,0 +1,260 @@
;/*****************************************************************************
; * @file: startup_LPC8xx.s
; * @purpose: CMSIS Cortex-M0+ Core Device Startup File
; * for the NXP LPC8xx Device Series
; * @version: V1.0
; * @date: 16. Aug. 2012
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
; *
; * Copyright (C) 2012 ARM Limited. All rights reserved.
; * ARM Limited (ARM) is supplying this software for use with Cortex-M0+
; * processor based microcontrollers. This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * 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.
; *
; *****************************************************************************/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00000180
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD SPI0_IRQHandler ; SPI0 controller
DCD SPI1_IRQHandler ; SPI1 controller
DCD 0 ; Reserved
DCD UART0_IRQHandler ; UART0
DCD UART1_IRQHandler ; UART1
DCD UART2_IRQHandler ; UART2
DCD 0 ; Reserved
DCD I2C1_IRQHandler ; I2C1 controller
DCD I2C0_IRQHandler ; I2C0 controller
DCD SCT_IRQHandler ; Smart Counter Timer
DCD MRT_IRQHandler ; Multi-Rate Timer
DCD CMP_IRQHandler ; Comparator
DCD WDT_IRQHandler ; PIO1 (0:11)
DCD BOD_IRQHandler ; Brown Out Detect
DCD FLASH_IRQHandler ; Non-Volatile Memory Controller
DCD WKT_IRQHandler ; Wakeup timer
DCD ADC_SEQA_IRQHandler ; ADC Sequence A Completion [Only on LPC82X]
DCD ADC_SEQB_IRQHanlder ; ADC Sequence B Completion [Only on LPC82X]
DCD ADC_THCMP_IRQHandler ; ADC Threshold compare [Only on LPC82X]
DCD ADC_OVR_IRQHandler ; ADC Overrun [Only on LPC82X]
DCD DMA_IRQHandler ; DMA Controller [Only on LPC82X]
DCD I2C2_IRQHandler ; I2C2 Controller [Only on LPC82X]
DCD I2C3_IRQHandler ; I2C3 Controller [Only on LPC82X]
DCD 0 ; Reserved
DCD PIN_INT0_IRQHandler ; PIO INT0
DCD PIN_INT1_IRQHandler ; PIO INT1
DCD PIN_INT2_IRQHandler ; PIO INT2
DCD PIN_INT3_IRQHandler ; PIO INT3
DCD PIN_INT4_IRQHandler ; PIO INT4
DCD PIN_INT5_IRQHandler ; PIO INT5
DCD PIN_INT6_IRQHandler ; PIO INT6
DCD PIN_INT7_IRQHandler ; PIO INT7
;// <h> Code Read Protection level (CRP)
;// <o> CRP_Level:
;// <0xFFFFFFFF=> Disabled
;// <0x4E697370=> NO_ISP
;// <0x12345678=> CRP1
;// <0x87654321=> CRP2
;// <0x43218765=> CRP3 (Are you sure?)
;// </h>
CRP_Level EQU 0xFFFFFFFF
IF :LNOT::DEF:NO_CRP
AREA |.ARM.__at_0x02FC|, CODE, READONLY
CRP_Key DCD 0xFFFFFFFF
ENDIF
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, = SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
; now, under COMMON lpc8xx_nmi.c and lpc8xx_nmi.h, a real NMI handler is created if NMI is enabled
; for particular peripheral.
;NMI_Handler PROC
; EXPORT NMI_Handler [WEAK]
; B .
; ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT NMI_Handler [WEAK]
EXPORT SPI0_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT I2C0_IRQHandler [WEAK]
EXPORT SCT_IRQHandler [WEAK]
EXPORT MRT_IRQHandler [WEAK]
EXPORT CMP_IRQHandler [WEAK]
EXPORT WDT_IRQHandler [WEAK]
EXPORT BOD_IRQHandler [WEAK]
EXPORT FLASH_IRQHandler [WEAK]
EXPORT WKT_IRQHandler [WEAK]
EXPORT PIN_INT0_IRQHandler [WEAK]
EXPORT PIN_INT1_IRQHandler [WEAK]
EXPORT PIN_INT2_IRQHandler [WEAK]
EXPORT PIN_INT3_IRQHandler [WEAK]
EXPORT PIN_INT4_IRQHandler [WEAK]
EXPORT PIN_INT5_IRQHandler [WEAK]
EXPORT PIN_INT6_IRQHandler [WEAK]
EXPORT PIN_INT7_IRQHandler [WEAK]
EXPORT ADC_SEQA_IRQHandler [WEAK]
EXPORT ADC_SEQB_IRQHanlder [WEAK]
EXPORT ADC_THCMP_IRQHandler [WEAK]
EXPORT ADC_OVR_IRQHandler [WEAK]
EXPORT DMA_IRQHandler [WEAK]
EXPORT I2C1_IRQHandler [WEAK]
EXPORT I2C2_IRQHandler [WEAK]
EXPORT I2C3_IRQHandler [WEAK]
NMI_Handler
SPI0_IRQHandler
SPI1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
I2C0_IRQHandler
SCT_IRQHandler
MRT_IRQHandler
CMP_IRQHandler
WDT_IRQHandler
BOD_IRQHandler
FLASH_IRQHandler
WKT_IRQHandler
PIN_INT0_IRQHandler
PIN_INT1_IRQHandler
PIN_INT2_IRQHandler
PIN_INT3_IRQHandler
PIN_INT4_IRQHandler
PIN_INT5_IRQHandler
PIN_INT6_IRQHandler
PIN_INT7_IRQHandler
ADC_SEQA_IRQHandler
ADC_SEQB_IRQHanlder
ADC_THCMP_IRQHandler
ADC_OVR_IRQHandler
DMA_IRQHandler
I2C1_IRQHandler
I2C2_IRQHandler
I2C3_IRQHandler
B .
ENDP
ALIGN
; User Initial Stack & Heap
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END

View File

@ -0,0 +1,130 @@
/*
* @brief LPC8xx Analog comparator driver
*
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initializes the ACMP */
void Chip_ACMP_Init(LPC_CMP_T *pACMP)
{
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_ACMP_PD);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ACOMP);
}
/* De-initializes the ACMP */
void Chip_ACMP_Deinit(LPC_CMP_T *pACMP)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ACOMP);
Chip_SYSCTL_PowerDown(SYSCTL_SLPWAKE_ACMP_PD);
}
/* Clears the ACMP interrupt (EDGECLR bit) */
void Chip_ACMP_EdgeClear(LPC_CMP_T *pACMP)
{
uint32_t reg = pACMP->CTRL & ~ACMP_CTRL_RESERVED;
/* Toggle EDGECLR bit high and then low */
pACMP->CTRL = reg | ACMP_EDGECLR_BIT;
pACMP->CTRL = reg & ~ACMP_EDGECLR_BIT;
}
/* Sets up ACMP edge selection */
void Chip_ACMP_SetEdgeSelection(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel)
{
uint32_t reg = pACMP->CTRL & ~(ACMP_EDGESEL_MASK | ACMP_CTRL_RESERVED);
/* Select edge for COMPEDGE */
pACMP->CTRL = reg | (uint32_t) edgeSel;
}
/* Selects positive voltage input */
void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, ACMP_POS_INPUT_T Posinput)
{
uint32_t reg = pACMP->CTRL & ~(ACMP_COMPVPSEL_MASK | ACMP_CTRL_RESERVED);
/* Select positive input */
pACMP->CTRL = reg | (uint32_t) Posinput;
}
/* Selects negative voltage input */
void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, ACMP_NEG_INPUT_T Neginput)
{
uint32_t reg = pACMP->CTRL & ~(ACMP_COMPVMSEL_MASK | ACMP_CTRL_RESERVED);
/* Select negative input */
pACMP->CTRL = reg | (uint32_t) Neginput;
}
/* Selects hysteresis level */
void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, ACMP_HYS_T hys)
{
uint32_t reg = pACMP->CTRL & ~(ACMP_HYSTERESIS_MASK | ACMP_CTRL_RESERVED);
/* Select negative input */
pACMP->CTRL = reg | (uint32_t) hys;
}
/* Helper function for setting up ACMP control */
void Chip_ACMP_SetupAMCPRefs(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel,
ACMP_POS_INPUT_T Posinput, ACMP_NEG_INPUT_T Neginput,
ACMP_HYS_T hys)
{
uint32_t reg = pACMP->CTRL & ~(ACMP_HYSTERESIS_MASK | ACMP_CTRL_RESERVED |
ACMP_COMPVMSEL_MASK | ACMP_COMPVPSEL_MASK | ACMP_EDGESEL_MASK);
/* Select negative input */
pACMP->CTRL = reg | (uint32_t) edgeSel | (uint32_t) Posinput |
(uint32_t) Neginput | (uint32_t) hys;
}
/* Sets up voltage ladder */
void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint32_t ladsel, bool ladrefVDDCMP)
{
uint32_t reg = pACMP->LAD & ~(ACMP_LADSEL_MASK | ACMP_LADREF_MASK | ACMP_LAD_RESERVED);
/* Setup voltage ladder and ladder reference */
if (ladrefVDDCMP) {
reg |= ACMP_LADREF_MASK;
}
pACMP->LAD = reg | (ladsel << 1);
}

View File

@ -0,0 +1,253 @@
/*
* @brief LPC8xx Analog comparator driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ACMP_8XX_H_
#define __ACMP_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup ACMP_8XX CHIP: LPC8xx Analog Comparator driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Analog Comparator register block structure
*/
typedef struct { /*!< ACMP Structure */
__IO uint32_t CTRL; /*!< Comparator control register */
__IO uint32_t LAD; /*!< Voltage ladder register */
} LPC_CMP_T;
/* Reserved bits masks for registers */
#define ACMP_CTRL_RESERVED (7|(1<<5)|(1<<7)|(0x3f<<14)|(1<<22)|(1<<24)|(0x1fu<<27))
#define ACMP_LAD_RESERVED (~0x7f)
#define ACMP_COMPSA_BIT (1 << 6) /* Comparator output control bit */
#define ACMP_COMPSTAT_BIT (1 << 21) /* Comparator status, reflects the state of the comparator output */
#define ACMP_COMPEDGE_BIT (1 << 23) /* Comparator edge-detect status */
#define ACMP_LADENAB_BIT (1 << 0) /* Voltage ladder enable bit */
/* EDGECLR interrupt clear bit, write 1, then 0 */
#define ACMP_EDGECLR_BIT (1 << 20)
#define ACMP_EDGESEL_MASK (0x3 << 3)
#define ACMP_COMPVPSEL_MASK (0x7 << 8)
#define ACMP_COMPVMSEL_MASK (0x7 << 11)
#define ACMP_HYSTERESIS_MASK (0x3 << 25)
#define ACMP_LADSEL_MASK (0x1F << 1)
#define ACMP_LADREF_MASK (0x1 << 6)
/** Edge selection for comparator */
typedef enum {
ACMP_EDGESEL_FALLING = (0 << 3), /* Set the COMPEDGE bit on falling edge */
ACMP_EDGESEL_RISING = (1 << 3), /* Set the COMPEDGE bit on rising edge */
ACMP_EDGESEL_BOTH = (2 << 3) /* Set the COMPEDGE bit on falling and rising edges */
} ACMP_EDGESEL_T;
/** Hysteresis selection for comparator */
typedef enum {
ACMP_HYS_NONE = (0 << 25), /* No hysteresis (the output will switch as the voltages cross) */
ACMP_HYS_5MV = (1 << 25), /* 5mV hysteresis */
ACMP_HYS_10MV = (2 << 25), /* 10mV hysteresis */
ACMP_HYS_20MV = (3 << 25) /* 20mV hysteresis */
} ACMP_HYS_T;
/**
* Analog Comparator positive input values
*/
typedef enum CHIP_ACMP_POS_INPUT {
ACMP_POSIN_VLO = (0 << 8), /*!< Voltage ladder output */
ACMP_POSIN_ACMP_I1 = (1 << 8), /*!< ACMP_I1 pin */
ACMP_POSIN_ACMP_I2 = (2 << 8), /*!< ACMP_I2 pin */
ACMP_POSIN_ACMP_I3 = (3 << 8), /*!< ACMP_I3 pin */
ACMP_POSIN_ACMP_I4 = (4 << 8), /*!< ACMP_I4 pin */
#if defined(CHIP_LPC82X)
ACMP_POSIN_INT_REF = (5 << 8), /*!< Internal reference voltage */
ACMP_POSIN_ADC_0 = (6 << 8), /*!< ADC_0 Input */
#else
ACMP_POSIN_INT_REF = (6 << 8), /*!< Internal reference voltage */
#endif
} ACMP_POS_INPUT_T;
/**
* Analog Comparator negative input values
*/
typedef enum CHIP_ACMP_NEG_INPUT {
ACMP_NEGIN_VLO = (0 << 11), /*!< Voltage ladder output */
ACMP_NEGIN_ACMP_I1 = (1 << 11), /*!< ACMP_I1 pin */
ACMP_NEGIN_ACMP_I2 = (2 << 11), /*!< ACMP_I2 pin */
ACMP_NEGIN_ACMP_I3 = (3 << 11), /*!< ACMP_I3 pin */
ACMP_NEGIN_ACMP_I4 = (4 << 11), /*!< ACMP_I4 pin */
#if defined(CHIP_LPC82X)
ACMP_NEGIN_INT_REF = (5 << 11), /*!< Internal reference voltage */
ACMP_NEGIN_ADC_0 = (6 << 11), /*!< ADC_0 Input */
#else
ACMP_NEGIN_INT_REF = (6 << 11) /*!< Internal reference voltage */
#endif
} ACMP_NEG_INPUT_T;
/**
* @brief Initializes the ACMP
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_Init(LPC_CMP_T *pACMP);
/**
* @brief Deinitializes the ACMP
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_Deinit(LPC_CMP_T *pACMP);
/**
* @brief Returns the current comparator status
* @param pACMP : Pointer to Analog Comparator block
* @return Status is an Or'ed value of ACMP_COMPSTAT_BIT or ACMP_COMPEDGE_BIT
*/
STATIC INLINE uint32_t Chip_ACMP_GetCompStatus(LPC_CMP_T *pACMP)
{
return pACMP->CTRL & (ACMP_COMPSTAT_BIT | ACMP_COMPEDGE_BIT);
}
/**
* @brief Clears the ACMP interrupt (EDGECLR bit)
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_EdgeClear(LPC_CMP_T *pACMP);
/**
* @brief Sets up ACMP edge selection
* @param pACMP : Pointer to Analog Comparator block
* @param edgeSel : Edge selection value
* @return Nothing
*/
void Chip_ACMP_SetEdgeSelection(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel);
/**
* @brief Synchronizes Comparator output to bus clock
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_EnableSyncCompOut(LPC_CMP_T *pACMP)
{
pACMP->CTRL = ACMP_COMPSA_BIT | (pACMP->CTRL & ~ACMP_CTRL_RESERVED);
}
/**
* @brief Sets comparator output to be used directly (no sync)
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_DisableSyncCompOut(LPC_CMP_T *pACMP)
{
pACMP->CTRL &= ~(ACMP_COMPSA_BIT | ACMP_CTRL_RESERVED);
}
/**
* @brief Selects positive voltage input
* @param pACMP : Pointer to Analog Comparator block
* @param Posinput : one of the positive input voltage sources
* @return Nothing
*/
void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, ACMP_POS_INPUT_T Posinput);
/**
* @brief Selects negative voltage input
* @param pACMP : Pointer to Analog Comparator block
* @param Neginput : one of the negative input voltage sources
* @return Nothing
*/
void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, ACMP_NEG_INPUT_T Neginput);
/**
* @brief Selects hysteresis level
* @param pACMP : Pointer to Analog Comparator block
* @param hys : Selected Hysteresis level
* @return Nothing
*/
void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, ACMP_HYS_T hys);
/**
* @brief Helper function for setting up ACMP control
* @param pACMP : Pointer to Analog Comparator block
* @param edgeSel : Edge selection value
* @param Posinput : one of the positive input voltage sources
* @param Neginput : one of the negative input voltage sources
* @param hys : Selected Hysteresis level
* @return Nothing
*/
void Chip_ACMP_SetupAMCPRefs(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel,
ACMP_POS_INPUT_T Posinput, ACMP_NEG_INPUT_T Neginput,
ACMP_HYS_T hys);
/**
* @brief Sets up voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @param ladsel : Voltage ladder value (0 .. 31)
* @param ladrefVDDCMP : Selects the reference voltage Vref for the voltage ladder
* : false for VDD, true for VDDCMP pin
* @return Nothing
*/
void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint32_t ladsel, bool ladrefVDDCMP);
/**
* @brief Enables voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_EnableVoltLadder(LPC_CMP_T *pACMP)
{
pACMP->LAD = ACMP_LADENAB_BIT | (pACMP->LAD & ~ACMP_LAD_RESERVED);
}
/**
* @brief Disables voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_DisableVoltLadder(LPC_CMP_T *pACMP)
{
pACMP->LAD &= ~(ACMP_LADENAB_BIT | ACMP_LAD_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ACMP_8XX_H_ */

View File

@ -0,0 +1,91 @@
/*
* @brief LPC82x ADC driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#include "adc_8xx.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the ADC peripheral */
void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags)
{
/* Power up ADC and enable ADC base clock */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_ADC_PD);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC);
/* Disable ADC interrupts */
pADC->INTEN = 0;
/* Set ADC control options */
pADC->CTRL = flags;
}
/* Shutdown ADC */
void Chip_ADC_DeInit(LPC_ADC_T *pADC)
{
pADC->INTEN = 0;
pADC->CTRL = 0;
/* Stop ADC clock and then power down ADC */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC);
Chip_SYSCTL_PowerDown(SYSCTL_SLPWAKE_ADC_PD);
}
/* Start ADC calibration */
void Chip_ADC_StartCalibration(LPC_ADC_T *pADC)
{
/* Set calibration mode */
pADC->CTRL |= ADC_CR_CALMODEBIT;
/* Clear ASYNC bit */
pADC->CTRL &= ~ADC_CR_ASYNMODE;
/* Setup ADC for about 500KHz (per UM) */
Chip_ADC_SetClockRate(pADC, 500000);
/* Clearn low power bit */
pADC->CTRL &= ~ADC_CR_LPWRMODEBIT;
/* Calibration is only complete when ADC_CR_CALMODEBIT bit has cleared */
}

View File

@ -0,0 +1,586 @@
/*
* @brief LPC82x ADC driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ADC_8XX_H_
#define __ADC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup ADC_8XX CHIP: LPC8xx A/D conversion driver (Available on LPC82x Family)
* @ingroup CHIP_8xx_Drivers
* @{
*/
/** Sequence index enumerations, used in various parts of the code for
register indexing and sequencer selection */
typedef enum {
ADC_SEQA_IDX,
ADC_SEQB_IDX
} ADC_SEQ_IDX_T;
/**
* @brief ADC register block structure
*/
typedef struct { /*!< ADCn Structure */
__IO uint32_t CTRL; /*!< A/D Control Register. The AD0CR register must be written to select the operating mode before A/D conversion can occur. */
__I uint32_t RESERVED0;
__IO uint32_t SEQ_CTRL[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Control Register. Controls triggering and channel selection for sonversion sequence. */
__IO uint32_t SEQ_GDAT[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Global Data Register. Contains the result of the most recent A/D conversion for sequence. */
__I uint32_t RESERVED1[2];
__I uint32_t DR[12]; /*!< A/D Channel Data Register. This register contains the result of the most recent conversion completed on channel n. */
__IO uint32_t THR_LOW[2]; /*!< A/D Low Compare Threshold Register 0 & 1. Contains the lower threshold level for automatic threshold comparison. */
__IO uint32_t THR_HIGH[2]; /*!< A/D High Compare Threshold Register 0 & 1. Contains the higher threshold level for automatic threshold comparison. */
__IO uint32_t CHAN_THRSEL; /*!< A/D Channel Threshold Select Register. Specifies which set of threshold compare registers to use. */
__IO uint32_t INTEN; /*!< A/D Interrupt Enable Register. This register contains enable bits that enable sequence-A, sequence-B, threshold compare and overrun interrupts. */
__IO uint32_t FLAGS; /*!< A/D Flags Register. This register contains interrupt flags. - To be checked */
__IO uint32_t TRM; /*!< A/D Trim Register. */
} LPC_ADC_T;
/** Maximum sample rate in Hz (12-bit conversions) */
#define ADC_MAX_SAMPLE_RATE 30000000
/**
* @brief ADC register support bitfields and mask
*/
/** ADC Control register bit fields */
#define ADC_CR_CLKDIV_MASK (0xFF << 0) /*!< Mask for Clock divider value */
#define ADC_CR_CLKDIV_BITPOS (0) /*!< Bit position for Clock divider value */
#define ADC_CR_ASYNMODE (1 << 8) /*!< Asynchronous mode enable bit */
#define ADC_CR_MODE10BIT (1 << 9) /*!< 10-bit mode enable bit */
#define ADC_CR_LPWRMODEBIT (1 << 10) /*!< Low power mode enable bit */
#define ADC_CR_CALMODEBIT (1 << 30) /*!< Self calibration cycle enable bit */
#define ADC_CR_BITACC(n) ((((n) & 0x1) << 9)) /*!< 12-bit or 10-bit ADC accuracy */
#define ADC_CR_CLKDIV(n) ((((n) & 0xFF) << 0)) /*!< The APB clock (PCLK) is divided by (this value plus one) to produce the clock for the A/D */
#define ADC_SAMPLE_RATE_CONFIG_MASK (ADC_CR_CLKDIV(0xFF) | ADC_CR_BITACC(0x01))
/** ADC Sequence Control register bit fields */
#define ADC_SEQ_CTRL_CHANSEL(n) (1 << (n)) /*!< Channel select macro */
#define ADC_SEQ_CTRL_CHANSEL_MASK (0xFFF) /*!< Channel select mask */
/** ADC hardware trigger sources in SEQ_CTRL */
#define ADC_SEQ_CTRL_HWTRIG_ARM_TXEV (0 << 12) /*!< HW trigger input - ARM TXEV */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_MAT0 (1 << 12) /*!< HW trigger input - Match output 0 of CT32B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_MAT1 (2 << 12) /*!< HW trigger input - Match output 1 of CT32B1 or SCT_OUT0 */
#define ADC_SEQ_CTRL_HWTRIG_SCT_OUT0 (2 << 12) /*!< HW trigger input - Match output 1 of CT32B1 or SCT_OUT0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_MAT0 (3 << 12) /*!< HW trigger input - Match output 0 of CT16B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_MAT1 (4 << 12) /*!< HW trigger input - Match output 1 of CT16B1 or SCT_OUT1 */
#define ADC_SEQ_CTRL_HWTRIG_SCT_OUT1 (4 << 12) /*!< HW trigger input - Match output 1 of CT16B1 or SCT_OUT1 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_CAP0 (5 << 12) /*!< HW trigger input - Capture input 0 of CT16B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B1_CAP0 (6 << 12) /*!< HW trigger input - Capture input 0 of CT16B1 */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_CAP0 (7 << 12) /*!< HW trigger input - Capture input 0 of CT32B1 */
#define ADC_SEQ_CTRL_HWTRIG_MASK (0x3F << 12) /*!< HW trigger input bitfield mask */
/** SEQ_CTRL register bit fields */
#define ADC_SEQ_CTRL_HWTRIG_POLPOS (1 << 18) /*!< HW trigger polarity - positive edge */
#define ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS (1 << 19) /*!< HW trigger bypass synchronisation */
#define ADC_SEQ_CTRL_START (1 << 26) /*!< Start conversion enable bit */
#define ADC_SEQ_CTRL_BURST (1 << 27) /*!< Repeated conversion enable bit */
#define ADC_SEQ_CTRL_SINGLESTEP (1 << 28) /*!< Single step enable bit */
#define ADC_SEQ_CTRL_LOWPRIO (1 << 29) /*!< High priority enable bit (regardless of name) */
#define ADC_SEQ_CTRL_MODE_EOS (1 << 30) /*!< Mode End of sequence enable bit */
#define ADC_SEQ_CTRL_SEQ_ENA (1UL << 31) /*!< Sequence enable bit */
/** ADC global data register bit fields */
#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF << 4) /*!< Result value mask */
#define ADC_SEQ_GDAT_RESULT_BITPOS (4) /*!< Result start bit position */
#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */
#define ADC_SEQ_GDAT_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */
#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */
#define ADC_SEQ_GDAT_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */
#define ADC_SEQ_GDAT_CHAN_MASK (0xF << 26) /*!< Channel number mask */
#define ADC_SEQ_GDAT_CHAN_BITPOS (26) /*!< Channel number bit position */
#define ADC_SEQ_GDAT_OVERRUN (1 << 30) /*!< Overrun bit */
#define ADC_SEQ_GDAT_DATAVALID (1UL << 31) /*!< Data valid bit */
/** ADC Data register bit fields */
#define ADC_DR_RESULT(n) ((((n) >> 4) & 0xFFF)) /*!< Macro for getting the ADC data value */
#define ADC_DR_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */
#define ADC_DR_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */
#define ADC_DR_THCMPRANGE(n) (((n) >> ADC_DR_THCMPRANGE_BITPOS) & 0x3)
#define ADC_DR_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */
#define ADC_DR_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */
#define ADC_DR_THCMPCROSS(n) (((n) >> ADC_DR_THCMPCROSS_BITPOS) & 0x3)
#define ADC_DR_CHAN_MASK (0xF << 26) /*!< Channel number mask */
#define ADC_DR_CHAN_BITPOS (26) /*!< Channel number bit position */
#define ADC_DR_CHANNEL(n) (((n) >> ADC_DR_CHAN_BITPOS) & 0xF) /*!< Channel number bit position */
#define ADC_DR_OVERRUN (1 << 30) /*!< Overrun bit */
#define ADC_DR_DATAVALID (1UL << 31) /*!< Data valid bit */
#define ADC_DR_DONE(n) (((n) >> 31))
/** ADC low/high Threshold register bit fields */
#define ADC_THR_VAL_MASK (0xFFF << 4) /*!< Threshold value bit mask */
#define ADC_THR_VAL_POS (4) /*!< Threshold value bit position */
/** ADC Threshold select register bit fields */
#define ADC_THRSEL_CHAN_SEL_THR1(n) (1 << (n)) /*!< Select THR1 register for channel n */
/** ADC Interrupt Enable register bit fields */
#define ADC_INTEN_SEQA_ENABLE (1 << 0) /*!< Sequence A Interrupt enable bit */
#define ADC_INTEN_SEQB_ENABLE (1 << 1) /*!< Sequence B Interrupt enable bit */
#define ADC_INTEN_SEQN_ENABLE(seq) (1 << (seq)) /*!< Sequence A/B Interrupt enable bit */
#define ADC_INTEN_OVRRUN_ENABLE (1 << 2) /*!< Overrun Interrupt enable bit */
#define ADC_INTEN_CMP_DISBALE (0) /*!< Disable comparison interrupt value */
#define ADC_INTEN_CMP_OUTSIDETH (1) /*!< Outside threshold interrupt value */
#define ADC_INTEN_CMP_CROSSTH (2) /*!< Crossing threshold interrupt value */
#define ADC_INTEN_CMP_MASK (3) /*!< Comparison interrupt value mask */
#define ADC_INTEN_CMP_ENABLE(isel, ch) (((isel) & ADC_INTEN_CMP_MASK) << ((2 * (ch)) + 3)) /*!< Interrupt selection for channel */
/** ADC Flags register bit fields */
#define ADC_FLAGS_THCMP_MASK(ch) (1 << (ch)) /*!< Threshold comparison status for channel */
#define ADC_FLAGS_OVRRUN_MASK(ch) (1 << (12 + (ch))) /*!< Overrun status for channel */
#define ADC_FLAGS_SEQA_OVRRUN_MASK (1 << 24) /*!< Seq A Overrun status */
#define ADC_FLAGS_SEQB_OVRRUN_MASK (1 << 25) /*!< Seq B Overrun status */
#define ADC_FLAGS_SEQN_OVRRUN_MASK(seq) (1 << (24 + (seq))) /*!< Seq A/B Overrun status */
#define ADC_FLAGS_SEQA_INT_MASK (1 << 28) /*!< Seq A Interrupt status */
#define ADC_FLAGS_SEQB_INT_MASK (1 << 29) /*!< Seq B Interrupt status */
#define ADC_FLAGS_SEQN_INT_MASK(seq) (1 << (28 + (seq)))/*!< Seq A/B Interrupt status */
#define ADC_FLAGS_THCMP_INT_MASK (1 << 30) /*!< Threshold comparison Interrupt status */
#define ADC_FLAGS_OVRRUN_INT_MASK (1UL << 31) /*!< Overrun Interrupt status */
/** ADC Trim register bit fields */
#define ADC_TRIM_VRANGE_HIGHV (0 << 5) /*!< Voltage range bit - High volatge (2.7V to 3.6V) */
#define ADC_TRIM_VRANGE_LOWV (1 << 5) /*!< Voltage range bit - Low volatge (1.8V to 2.7V) */
/** ADC Register reserved bit masks */
#define ADC_CHAN_THRSEL_RES 0xFFFFF000
#define ADC_INTEN_RES 0xF8000000
#define ADC_SEQ_CTRL_RES ((7 << 15) | (0x3F << 20))
/**
* @brief Initialize the ADC peripheral
* @param pADC : The base of ADC peripheral on the chip
* @param flags : ADC flags for init (ADC_CR_MODE10BIT and/or ADC_CR_LPWRMODEBIT)
* @return Nothing
* @note To select low-power ADC mode, enable the ADC_CR_LPWRMODEBIT flag.
* To select 10-bit conversion mode, enable the ADC_CR_MODE10BIT flag.<br>
* Example: Chip_ADC_Init(LPC_ADC, (ADC_CR_MODE10BIT | ADC_CR_LPWRMODEBIT));
*/
void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags);
/**
* @brief Shutdown ADC
* @param pADC : The base of ADC peripheral on the chip
* @return Nothing
* @note Disables the ADC clocks and ADC power
*/
void Chip_ADC_DeInit(LPC_ADC_T *pADC);
/**
* @brief Set ADC divider
* @param pADC : The base of ADC peripheral on the chip
* @param div : ADC divider value to set minus 1
* @return Nothing
* @note The value is used as a divider to generate the ADC
* clock rate from the ADC input clock. The ADC input clock is based
* on the system clock. Valid values for this function are from 0 to 255
* with 0=divide by 1, 1=divide by 2, 2=divide by 3, etc.<br>
* Do not decrement this value by 1.<br>
* To set the ADC clock rate to 1MHz, use the following function:<br>
* Chip_ADC_SetDivider(LPC_ADC, (Chip_Clock_GetSystemClockRate() / 1000000) - 1);
*/
STATIC INLINE void Chip_ADC_SetDivider(LPC_ADC_T *pADC, uint8_t div)
{
uint32_t temp;
temp = pADC->CTRL & ~(ADC_CR_CLKDIV_MASK);
pADC->CTRL = temp | (uint32_t) div;
}
/**
* @brief Set ADC clock rate
* @param pADC : The base of ADC peripheral on the chip
* @param rate : rate in Hz to set ADC clock to (maximum ADC_MAX_SAMPLE_RATE)
* @return Nothing
* @note When ADC is set to ADC_CR_ASYNMODE this function has no effect. The
* rate mentioned in @a rate is the sampling clock rate and not the frequency at
* at which the conversion will be done. Example setting @a rate to 30 MHz will
* get a sampling rate of 1.2M samples per second.
*/
STATIC INLINE void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate)
{
Chip_ADC_SetDivider(pADC, (uint8_t) (Chip_Clock_GetSystemClockRate() / rate) - 1);
}
/**
* @brief Get ADC divider
* @param pADC : The base of ADC peripheral on the chip
* @return the current ADC divider
* @note This function returns the divider that is used to generate the
* ADC frequency. The returned value must be incremented by 1. The
* frequency can be determined with the following function:<br>
* adc_freq = Chip_Clock_GetSystemClockRate() / (Chip_ADC_GetDivider(LPC_ADC) + 1);
*/
STATIC INLINE uint8_t Chip_ADC_GetDivider(LPC_ADC_T *pADC)
{
return pADC->CTRL & ADC_CR_CLKDIV_MASK;
}
/**
* @brief Start ADC calibration
* @param pADC : The base of ADC peripheral on the chip
* @return Nothing
* @note Calibration is not done as part of Chip_ADC_Init(), but
* is required after the call to Chip_ADC_Init() or after returning
* from a power-down state. Calibration may alter the ADC_CR_ASYNMODE
* and ADC_CR_LPWRMODEBIT flags ni the CTRL register.
*/
void Chip_ADC_StartCalibration(LPC_ADC_T *pADC);
/**
* @brief Start ADC calibration
* @param pADC : The base of ADC peripheral on the chip
* @return TRUE if calibration is complete, otherwise FALSE.
*/
STATIC INLINE bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC)
{
return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0);
}
/**
* @brief Helper function for safely setting ADC sequencer register bits
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to set bits for
* @param bits : Or'ed bits of a sequencer register to set
* @return Nothing
* @note This function will safely set the ADC sequencer register bits
* while maintaining bits 20..25 as 0, regardless of the read state of those bits.
*/
STATIC INLINE void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
{
pADC->SEQ_CTRL[seqIndex] = (pADC->SEQ_CTRL[seqIndex] & ~ADC_SEQ_CTRL_RES) | bits;
}
/**
* @brief Helper function for safely clearing ADC sequencer register bits
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to clear bits for
* @param bits : Or'ed bits of a sequencer register to clear
* @return Nothing
* @note This function will safely clear the ADC sequencer register bits
* while maintaining bits 20..25 as 0, regardless of the read state of those bits.
*/
STATIC INLINE void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
{
pADC->SEQ_CTRL[seqIndex] = pADC->SEQ_CTRL[seqIndex] & ~(ADC_SEQ_CTRL_RES | bits);
}
/**
* @brief Sets up ADC conversion sequencer A or B
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to setup
* @param options : OR'ed Sequencer options to setup (see notes)
* @return Nothing
* @note Sets up sequencer options for a conversion sequence. This function
* should be used to setup the selected channels for the sequence, the sequencer
* trigger, the trigger polarity, synchronization bypass, priority, and mode. All
* options are passed to the functions as a OR'ed list of values. This function will
* disable/clear the sequencer start/burst/single step/enable if they are enabled.<br>
* Select the channels by OR'ing in one or more ADC_SEQ_CTRL_CHANSEL(ch) values.<br>
* Select the hardware trigger by OR'ing in one ADC_SEQ_CTRL_HWTRIG_* value.<br>
* Select a positive edge hardware trigger by OR'ing in ADC_SEQ_CTRL_HWTRIG_POLPOS.<br>
* Select trigger bypass synchronisation by OR'ing in ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS.<br>
* Select ADC single step on trigger/start by OR'ing in ADC_SEQ_CTRL_SINGLESTEP.<br>
* Select higher priority conversion on the other sequencer by OR'ing in ADC_SEQ_CTRL_LOWPRIO.<br>
* Select end of seqeuence instead of end of conversion interrupt by OR'ing in ADC_SEQ_CTRL_MODE_EOS.<br>
* Example for setting up sequencer A (channels 0-2, trigger on high edge of PIO0_2, interrupt on end of sequence):<br>
* Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (
* ADC_SEQ_CTRL_CHANSEL(0) | ADC_SEQ_CTRL_CHANSEL(1) | ADC_SEQ_CTRL_CHANSEL(2) |
* ADC_SEQ_CTRL_HWTRIG_PIO0_2 | ADC_SEQ_CTRL_HWTRIG_POLPOS | ADC_SEQ_CTRL_MODE_EOS));
*/
STATIC INLINE void Chip_ADC_SetupSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t options)
{
pADC->SEQ_CTRL[seqIndex] = options;
}
/**
* @brief Enables a sequencer
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to enable
* @return Nothing
*/
STATIC INLINE void Chip_ADC_EnableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
}
/**
* @brief Disables a sequencer
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to disable
* @return Nothing
*/
STATIC INLINE void Chip_ADC_DisableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
}
/**
* @brief Forces a sequencer trigger event (software trigger of ADC)
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to start
* @return Nothing
* @note This function sets the START bit for the sequencer to force a
* single conversion sequence or a single step conversion.
*/
STATIC INLINE void Chip_ADC_StartSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_START);
}
/**
* @brief Starts sequencer burst mode
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to start burst on
* @return Nothing
* @note This function sets the BURST bit for the sequencer to force
* continuous conversion. Use Chip_ADC_StopBurstSequencer() to stop the
* ADC burst sequence.
*/
STATIC INLINE void Chip_ADC_StartBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
}
/**
* @brief Stops sequencer burst mode
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to stop burst on
* @return Nothing
*/
STATIC INLINE void Chip_ADC_StopBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
}
/** ADC sequence global data register threshold comparison range enumerations */
typedef enum {
ADC_DR_THCMPRANGE_INRANGE,
ADC_DR_THCMPRANGE_RESERVED,
ADC_DR_THCMPRANGE_BELOW,
ADC_DR_THCMPRANGE_ABOVE
} ADC_DR_THCMPRANGE_T;
/** ADC sequence global data register threshold comparison cross enumerations */
typedef enum {
ADC_DR_THCMPCROSS_NOCROSS,
ADC_DR_THCMPCROSS_RESERVED,
ADC_DR_THCMPCROSS_DOWNWARD,
ADC_DR_THCMPCROSS_UPWARD
} ADC_DR_THCMPCROSS_T;
/**
* @brief Read a ADC sequence global data register
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to read
* @return Current raw value of the ADC sequence A or B global data register
* @note This function returns the raw value of the data register and clears
* the overrun and datavalid status for the register. Once this register is read,
* the following functions can be used to parse the raw value:<br>
* uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
* uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
* ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
* ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
* uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
* bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
* bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
*/
STATIC INLINE uint32_t Chip_ADC_GetSequencerDataReg(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
return pADC->SEQ_GDAT[seqIndex];
}
/**
* @brief Read a ADC data register
* @param pADC : The base of ADC peripheral on the chip
* @param index : Data register to read, 1-8
* @return Current raw value of the ADC data register
* @note This function returns the raw value of the data register and clears
* the overrun and datavalid status for the register. Once this register is read,
* the following functions can be used to parse the raw value:<br>
* uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
* uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
* ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
* ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
* uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
* bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
* bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
*/
STATIC INLINE uint32_t Chip_ADC_GetDataReg(LPC_ADC_T *pADC, uint8_t index)
{
return pADC->DR[index];
}
/**
* @brief Set Threshold low value in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0)
* @param value : Threshold low data value (should be 12-bit value)
* @return None
*/
STATIC INLINE void Chip_ADC_SetThrLowValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
{
pADC->THR_LOW[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
}
/**
* @brief Set Threshold high value in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0)
* @param value : Threshold high data value (should be 12-bit value)
* @return None
*/
STATIC INLINE void Chip_ADC_SetThrHighValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
{
pADC->THR_HIGH[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
}
/**
* @brief Select threshold 0 values for comparison for selected channels
* @param pADC : The base of ADC peripheral on the chip
* @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
* @return None
* @note Select multiple channels to use the threshold 0 comparison.<br>
* Example:<br>
* Chip_ADC_SelectTH0Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(1) | ADC_THRSEL_CHAN_SEL_THR1(2))); // Selects channels 1 and 2 for threshold 0
*/
STATIC INLINE void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels)
{
pADC->CHAN_THRSEL = pADC->CHAN_THRSEL & ~(ADC_CHAN_THRSEL_RES | channels);
}
/**
* @brief Select threshold 1 value for comparison for selected channels
* @param pADC : The base of ADC peripheral on the chip
* @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
* @return None
* @note Select multiple channels to use the 1 threshold comparison.<br>
* Example:<br>
* Chip_ADC_SelectTH1Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(4) | ADC_THRSEL_CHAN_SEL_THR1(5))); // Selects channels 4 and 5 for 1 threshold
*/
STATIC INLINE void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels)
{
pADC->CHAN_THRSEL = (pADC->CHAN_THRSEL & ~ADC_CHAN_THRSEL_RES) | channels;
}
/**
* @brief Enable interrupts in ADC (sequencers A/B and overrun)
* @param pADC : The base of ADC peripheral on the chip
* @param intMask : Interrupt values to be enabled (see notes)
* @return None
* @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
* ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to enable the
* specific ADC interrupts.
*/
STATIC INLINE void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask)
{
pADC->INTEN = (pADC->INTEN & ~ADC_INTEN_RES) | intMask;
}
/**
* @brief Disable interrupts in ADC (sequencers A/B and overrun)
* @param pADC : The base of ADC peripheral on the chip
* @param intMask : Interrupt values to be disabled (see notes)
* @return None
* @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
* ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to disable the
* specific ADC interrupts.
*/
STATIC INLINE void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask)
{
pADC->INTEN = pADC->INTEN & ~(ADC_INTEN_RES | intMask);
}
/** Threshold interrupt event options */
typedef enum {
ADC_INTEN_THCMP_DISABLE,
ADC_INTEN_THCMP_OUTSIDE,
ADC_INTEN_THCMP_CROSSING,
} ADC_INTEN_THCMP_T;
/**
* @brief Enable a threshold event interrupt in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param ch : ADC channel to set threshold inetrrupt for, 1-8
* @param thInt : Selected threshold interrupt type
* @return None
*/
STATIC INLINE void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt)
{
pADC->INTEN = (pADC->INTEN & ~(ADC_INTEN_RES | (3 << (3 + (ch * 2))))) | (thInt << (3 + (ch * 2)));
}
/**
* @brief Get flags register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @return Flags register value (ORed ADC_FLAG* values)
* @note Mask the return value of this function with the ADC_FLAGS_*
* definitions to determine the overall ADC interrupt events.<br>
* Example:<br>
* if (Chip_ADC_GetFlags(LPC_ADC) & ADC_FLAGS_THCMP_MASK(3) // Check of threshold comp status for ADC channel 3
*/
STATIC INLINE uint32_t Chip_ADC_GetFlags(LPC_ADC_T *pADC)
{
return pADC->FLAGS;
}
/**
* @brief Clear flags register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param flags : An Or'ed values of ADC_FLAGS_* values to clear
* @return Flags register value (ORed ADC_FLAG* values)
*/
STATIC INLINE void Chip_ADC_ClearFlags(LPC_ADC_T *pADC, uint32_t flags)
{
pADC->FLAGS = flags;
}
/**
* @brief Set Trim register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param trim : Trim value (ADC_TRIM_VRANGE_HIGHV or ADC_TRIM_VRANGE_LOWV)
* @return None
*/
STATIC INLINE void Chip_ADC_SetTrim(LPC_ADC_T *pADC, uint32_t trim)
{
pADC->TRM = trim;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ADC_8XX_H_ */

View File

@ -0,0 +1,117 @@
/*
* @brief LPC8xx Cyclic Redundancy Check (CRC) Engine driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize CRC engine */
void Chip_CRC_Init(void)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CRC);
}
/* De-initialize CRC engine */
void Chip_CRC_Deinit(void)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_CRC);
}
/* Sets up the CRC engine with defaults based on the polynomial to be used */
void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly)
{
switch (poly) {
case CRC_POLY_CRC16:
Chip_CRC_UseCRC16();
break;
case CRC_POLY_CRC32:
Chip_CRC_UseCRC32();
break;
case CRC_POLY_CCITT:
default:
Chip_CRC_UseCCITT();
break;
}
}
/* configure CRC engine and compute CCITT checksum from 8-bit data */
uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes)
{
Chip_CRC_UseCCITT();
while (bytes > 0) {
Chip_CRC_Write8(*data);
data++;
bytes--;
}
return Chip_CRC_Sum();
}
/* Convenience function for computing a standard CRC16 checksum from 16-bit data block */
uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords)
{
Chip_CRC_UseCRC16();
while (hwords > 0) {
Chip_CRC_Write16(*data);
data++;
hwords--;
}
return Chip_CRC_Sum();
}
/* Convenience function for computing a standard CRC32 checksum from 32-bit data block */
uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words)
{
Chip_CRC_UseCRC32();
while (words > 0) {
Chip_CRC_Write32(*data);
data++;
words--;
}
return Chip_CRC_Sum();
}

View File

@ -0,0 +1,262 @@
/*
* @brief LPC8xx Cyclic Redundancy Check (CRC) Engine driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __CRC_8XX_H_
#define __CRC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CRC_8XX CHIP: LPC8xx Cyclic Redundancy Check Engine driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief CRC register block structure
*/
typedef struct { /*!< CRC Structure */
__IO uint32_t MODE; /*!< CRC Mode Register */
__IO uint32_t SEED; /*!< CRC SEED Register */
union {
__I uint32_t SUM; /*!< CRC Checksum Register. */
__O uint32_t WRDATA32; /*!< CRC Data Register: write size 32-bit*/
__O uint16_t WRDATA16; /*!< CRC Data Register: write size 16-bit*/
__O uint8_t WRDATA8; /*!< CRC Data Register: write size 8-bit*/
};
} LPC_CRC_T;
/*
* @brief CRC MODE register description
*/
#define CRC_MODE_POLY_BITMASK ((0x03)) /** CRC polynomial Bit mask */
#define CRC_MODE_POLY_CCITT (0x00) /** Select CRC-CCITT polynomial */
#define CRC_MODE_POLY_CRC16 (0x01) /** Select CRC-16 polynomial */
#define CRC_MODE_POLY_CRC32 (0x02) /** Select CRC-32 polynomial */
#define CRC_MODE_WRDATA_BITMASK (0x03 << 2) /** CRC WR_Data Config Bit mask */
#define CRC_MODE_WRDATA_BIT_RVS (1 << 2) /** Select Bit order reverse for WR_DATA (per byte) */
#define CRC_MODE_WRDATA_CMPL (1 << 3) /** Select One's complement for WR_DATA */
#define CRC_MODE_SUM_BITMASK (0x03 << 4) /** CRC Sum Config Bit mask */
#define CRC_MODE_SUM_BIT_RVS (1 << 4) /** Select Bit order reverse for CRC_SUM */
#define CRC_MODE_SUM_CMPL (1 << 5) /** Select One's complement for CRC_SUM */
#define MODE_CFG_CCITT (0x00) /** Pre-defined mode word for default CCITT setup */
#define MODE_CFG_CRC16 (0x15) /** Pre-defined mode word for default CRC16 setup */
#define MODE_CFG_CRC32 (0x36) /** Pre-defined mode word for default CRC32 setup */
#define CRC_SEED_CCITT (0x0000FFFF)/** Initial seed value for CCITT mode */
#define CRC_SEED_CRC16 (0x00000000)/** Initial seed value for CRC16 mode */
#define CRC_SEED_CRC32 (0xFFFFFFFF)/** Initial seed value for CRC32 mode */
/**
* @brief CRC polynomial
*/
typedef enum IP_CRC_001_POLY {
CRC_POLY_CCITT = CRC_MODE_POLY_CCITT, /**< CRC-CCIT polynomial */
CRC_POLY_CRC16 = CRC_MODE_POLY_CRC16, /**< CRC-16 polynomial */
CRC_POLY_CRC32 = CRC_MODE_POLY_CRC32, /**< CRC-32 polynomial */
CRC_POLY_LAST,
} CRC_POLY_T;
/**
* @brief Initializes the CRC Engine
* @return Nothing
*/
void Chip_CRC_Init(void);
/**
* @brief Deinitializes the CRC Engine
* @return Nothing
*/
void Chip_CRC_Deinit(void);
/**
* @brief Set the polynomial used for the CRC calculation
* @param poly : The enumerated polynomial to be used
* @param flags : An Or'ed value of flags that setup the mode
* @return Nothing
* @note Flags for setting up the mode word include CRC_MODE_WRDATA_BIT_RVS,
* CRC_MODE_WRDATA_CMPL, CRC_MODE_SUM_BIT_RVS, and CRC_MODE_SUM_CMPL.
*/
STATIC INLINE void Chip_CRC_SetPoly(CRC_POLY_T poly, uint32_t flags)
{
LPC_CRC->MODE = (uint32_t) poly | flags;
}
/**
* @brief Sets up the CRC engine for CRC16 mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCRC16(void)
{
LPC_CRC->MODE = MODE_CFG_CRC16;
LPC_CRC->SEED = CRC_SEED_CRC16;
}
/**
* @brief Sets up the CRC engine for CRC32 mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCRC32(void)
{
LPC_CRC->MODE = MODE_CFG_CRC32;
LPC_CRC->SEED = CRC_SEED_CRC32;
}
/**
* @brief Sets up the CRC engine for CCITT mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCCITT(void)
{
LPC_CRC->MODE = MODE_CFG_CCITT;
LPC_CRC->SEED = CRC_SEED_CCITT;
}
/**
* @brief Engage the CRC engine with defaults based on the polynomial to be used
* @param poly : The enumerated polynomial to be used
* @return Nothing
*/
void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly);
/**
* @brief Set the CRC Mode bits
* @param mode : Mode value
* @return Nothing
*/
STATIC INLINE void Chip_CRC_SetMode(uint32_t mode)
{
LPC_CRC->MODE = mode;
}
/**
* @brief Get the CRC Mode bits
* @return The current value of the CRC Mode bits
*/
STATIC INLINE uint32_t Chip_CRC_GetMode(void)
{
return LPC_CRC->MODE;
}
/**
* @brief Set the seed bits used by the CRC_SUM register
* @param seed : Seed value
* @return Nothing
*/
STATIC INLINE void Chip_CRC_SetSeed(uint32_t seed)
{
LPC_CRC->SEED = seed;
}
/**
* @brief Get the CRC seed value
* @return Seed value
*/
STATIC INLINE uint32_t Chip_CRC_GetSeed(void)
{
return LPC_CRC->SEED;
}
/**
* @brief Convenience function for writing 8-bit data to the CRC engine
* @param data : 8-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write8(uint8_t data)
{
LPC_CRC->WRDATA8 = data;
}
/**
* @brief Convenience function for writing 16-bit data to the CRC engine
* @param data : 16-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write16(uint16_t data)
{
LPC_CRC->WRDATA16 = data;
}
/**
* @brief Convenience function for writing 32-bit data to the CRC engine
* @param data : 32-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write32(uint32_t data)
{
LPC_CRC->WRDATA32 = data;
}
/**
* @brief Gets the CRC Sum based on the Mode and Seed as previously configured
* @return CRC Checksum value
*/
STATIC INLINE uint32_t Chip_CRC_Sum(void)
{
return LPC_CRC->SUM;
}
/**
* @brief Convenience function for computing a standard CCITT checksum from an 8-bit data block
* @param data : Pointer to the block of 8-bit data
* @param bytes : The number of bytes pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes);
/**
* @brief Convenience function for computing a standard CRC16 checksum from 16-bit data block
* @param data : Pointer to the block of 16-bit data
* @param hwords : The number of 16 byte entries pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords);
/**
* @brief Convenience function for computing a standard CRC32 checksum from 32-bit data block
* @param data : Pointer to the block of 32-bit data
* @param words : The number of 32-bit entries pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CRC_8XX_H_ */

View File

@ -0,0 +1,149 @@
/*
* @brief LPC82x DMA chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase()
function if a DMA SRAM table is needed. This table is correctly aligned for
the DMA controller. */
#ifdef __ICCARM__
#define ASTR(str) #str
#define ALIGN(x) _Pragma(ASTR(data_alignment=##x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif
/* Alignment of 512 bytes */
#define DMA_ALIGN ALIGN(512)
DMA_ALIGN DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL];
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
void ChipEz_DMA_Init(uint32_t isEnableIRQ)
{
Chip_DMA_Init(LPC_DMA);
Chip_DMA_Enable(LPC_DMA);
Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
if (isEnableIRQ)
NVIC_EnableIRQ(DMA_IRQn);
}
/**
* Initialize DMA parameters specific to a channel
*
* @param channel
* @param src_address
* @param dst_address
* @param xfr_width
* @param length_bytes
*/
void ChipEz_DMA_InitChannel( DMA_CHID_T channel, uint32_t src_address, uint32_t src_increment,
uint32_t dst_address, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes, uint32_t priority)
{
Chip_DMA_EnableChannel(LPC_DMA, channel);
Chip_DMA_EnableIntChannel(LPC_DMA, channel);
Chip_DMA_SetupChannelConfig(LPC_DMA, channel, DMA_CFG_PERIPHREQEN |
DMA_CFG_CHPRIORITY(priority));
if (src_increment != DMA_XFERCFG_SRCINC_0) {
Chip_DMA_Table[channel].source = DMA_ADDR((src_address + length_bytes)
- (1UL << xfr_width));
} else {
Chip_DMA_Table[channel].source = DMA_ADDR(src_address);
}
if (dst_increment != DMA_XFERCFG_DSTINC_0) {
Chip_DMA_Table[channel].dest = DMA_ADDR((dst_address + length_bytes)
- (1UL << xfr_width));
} else {
Chip_DMA_Table[channel].dest = DMA_ADDR(dst_address);
}
Chip_DMA_Table[channel].next = DMA_ADDR(0);
}
/**
* Start the DMA transfer
*
* @param channel
* @param src_increment
* @param dst_increment
* @param xfr_width
* @param length_bytes
*/
void ChipEz_DMA_StartTransfer(DMA_CHID_T channel, uint32_t src_increment, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes)
{
uint32_t xfer_count;
/* Calculate transfer_count ( length in terms of transfers) */
xfer_count = (xfr_width == DMA_XFERCFG_WIDTH_8) ? length_bytes :
(xfr_width == DMA_XFERCFG_WIDTH_16) ? (length_bytes >> 1) :
(length_bytes >> 2);
Chip_DMA_SetupChannelTransfer(LPC_DMA, channel,
(DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA | DMA_XFERCFG_SWTRIG |
xfr_width | src_increment | dst_increment |
DMA_XFERCFG_XFERCOUNT(xfer_count)));
}
bool ChipEzr_DMA_Transfer( DMA_CHID_T channel, uint32_t src_address, uint32_t src_increment,
uint32_t dst_address, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes, uint32_t priority)
{
if ((Chip_DMA_GetBusyChannels(LPC_DMA) & (1 << channel)) != 0)
return FALSE;
ChipEz_DMA_InitChannel(channel, src_address, src_increment, dst_address, dst_increment, xfr_width, length_bytes, priority);
ChipEz_DMA_StartTransfer(channel, src_increment, dst_increment, xfr_width, length_bytes);
return TRUE;
}
void ChipEz_DMA_AbortChannel(DMA_CHID_T ch) {
Chip_DMA_DisableChannel(LPC_DMA, ch);
while ((Chip_DMA_GetBusyChannels(LPC_DMA) & (1 << ch)) != 0) {}
Chip_DMA_AbortChannel(LPC_DMA, ch);
Chip_DMA_ClearErrorIntChannel(LPC_DMA, ch);
}

View File

@ -0,0 +1,810 @@
/*
* @brief LPC8xx DMA chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __DMA_8XX_H_
#define __DMA_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup DMA_8XX CHIP: LPC8xx DMA Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief DMA Controller shared registers structure
*/
typedef struct { /*!< DMA shared registers structure */
__IO uint32_t ENABLESET; /*!< DMA Channel Enable read and Set for all DMA channels */
__I uint32_t RESERVED0;
__O uint32_t ENABLECLR; /*!< DMA Channel Enable Clear for all DMA channels */
__I uint32_t RESERVED1;
__I uint32_t ACTIVE; /*!< DMA Channel Active status for all DMA channels */
__I uint32_t RESERVED2;
__I uint32_t BUSY; /*!< DMA Channel Busy status for all DMA channels */
__I uint32_t RESERVED3;
__IO uint32_t ERRINT; /*!< DMA Error Interrupt status for all DMA channels */
__I uint32_t RESERVED4;
__IO uint32_t INTENSET; /*!< DMA Interrupt Enable read and Set for all DMA channels */
__I uint32_t RESERVED5;
__O uint32_t INTENCLR; /*!< DMA Interrupt Enable Clear for all DMA channels */
__I uint32_t RESERVED6;
__IO uint32_t INTA; /*!< DMA Interrupt A status for all DMA channels */
__I uint32_t RESERVED7;
__IO uint32_t INTB; /*!< DMA Interrupt B status for all DMA channels */
__I uint32_t RESERVED8;
__O uint32_t SETVALID; /*!< DMA Set ValidPending control bits for all DMA channels */
__I uint32_t RESERVED9;
__O uint32_t SETTRIG; /*!< DMA Set Trigger control bits for all DMA channels */
__I uint32_t RESERVED10;
__O uint32_t ABORT; /*!< DMA Channel Abort control for all DMA channels */
} LPC_DMA_COMMON_T;
/**
* @brief DMA Controller shared registers structure
*/
typedef struct { /*!< DMA channel register structure */
__IO uint32_t CFG; /*!< DMA Configuration register */
__I uint32_t CTLSTAT; /*!< DMA Control and status register */
__IO uint32_t XFERCFG; /*!< DMA Transfer configuration register */
__I uint32_t RESERVED;
} LPC_DMA_CHANNEL_T;
/* Reserved bits masks... */
#define DMA_CFG_RESERVED ((3<<2)|(1<<7)|(3<<12)|0xfffc0000)
#define DMA_CTLSTAT_RESERVED (~(1|(1<<2)))
#define DMA_XFERCFG_RESERVED ((3<<6)|(3<<10)|(0x3fu<<26))
/* DMA channel mapping - each channel is mapped to an individual peripheral
and direction or a DMA imput mux trigger */
typedef enum {
DMAREQ_USART0_RX, /*!< USART0 receive DMA channel */
DMA_CH0 = DMAREQ_USART0_RX,
DMAREQ_USART0_TX, /*!< USART0 transmit DMA channel */
DMA_CH1 = DMAREQ_USART0_TX,
DMAREQ_USART1_RX, /*!< USART1 receive DMA channel */
DMA_CH2 = DMAREQ_USART1_RX,
DMAREQ_USART1_TX, /*!< USART1 transmit DMA channel */
DMA_CH3 = DMAREQ_USART1_TX,
DMAREQ_USART2_RX, /*!< USART2 receive DMA channel */
DMA_CH4 = DMAREQ_USART2_RX,
DMAREQ_USART2_TX, /*!< USART2 transmit DMA channel */
DMA_CH5 = DMAREQ_USART2_TX,
DMAREQ_SPI0_RX,
DMA_CH6 = DMAREQ_SPI0_RX, /*!< SPI0 receive DMA channel */
DMAREQ_SPI0_TX,
DMA_CH7 = DMAREQ_SPI0_TX, /*!< SPI0 transmit DMA channel */
DMAREQ_SPI1_RX,
DMA_CH8 = DMAREQ_SPI1_RX, /*!< SPI1 receive DMA channel */
DMAREQ_SPI1_TX,
DMA_CH9 = DMAREQ_SPI1_TX, /*!< SPI1 transmit DMA channel */
DMAREQ_I2C0_MST,
DMA_CH10 = DMAREQ_I2C0_MST, /*!< I2C0 Master DMA channel */
DMAREQ_I2C0_SLV,
DMA_CH11 = DMAREQ_I2C0_SLV, /*!< I2C0 Slave DMA channel */
DMAREQ_I2C1_MST,
DMA_CH12 = DMAREQ_I2C1_MST, /*!< I2C1 Master DMA channel */
DMAREQ_I2C1_SLV,
DMA_CH13 = DMAREQ_I2C1_SLV, /*!< I2C1 Slave DMA channel */
DMAREQ_I2C2_MST,
DMA_CH14 = DMAREQ_I2C2_MST, /*!< I2C2 Master DMA channel */
DMAREQ_I2C2_SLV,
DMA_CH15 = DMAREQ_I2C2_SLV, /*!< I2C2 Slave DMA channel */
DMAREQ_I2C3_MST,
DMA_CH16 = DMAREQ_I2C3_MST, /*!< I2C2 Master DMA channel */
DMAREQ_I2C3_SLV,
DMA_CH17 = DMAREQ_I2C3_SLV, /*!< I2C2 Slave DMA channel */
} DMA_CHID_T;
/* On LPC82x, Max DMA channel is 18 */
#define MAX_DMA_CHANNEL (DMA_CH17 + 1)
/* Reserved bits masks... */
#define DMA_COMMON_RESERVED (~(0UL) << MAX_DMA_CHANNEL)
#define DMA_ENABLESET_RESERVED DMA_COMMON_RESERVED
#define DMA_ENABLECLR_RESERVED DMA_COMMON_RESERVED
#define DMA_ACTIVE_RESERVED DMA_COMMON_RESERVED
#define DMA_BUSY_RESERVED DMA_COMMON_RESERVED
#define DMA_ERRINT_RESERVED DMA_COMMON_RESERVED
#define DMA_INTENSET_RESERVED DMA_COMMON_RESERVED
#define DMA_INTENCLR_RESERVED DMA_COMMON_RESERVED
#define DMA_INTA_RESERVED DMA_COMMON_RESERVED
#define DMA_INTB_RESERVED DMA_COMMON_RESERVED
#define DMA_SETVALID_RESERVED DMA_COMMON_RESERVED
#define DMA_SETTRIG_RESERVED DMA_COMMON_RESERVED
#define DMA_ABORT_RESERVED DMA_COMMON_RESERVED
/**
* @brief DMA Controller register block structure
*/
typedef struct { /*!< DMA Structure */
__IO uint32_t CTRL; /*!< DMA control register */
__I uint32_t INTSTAT; /*!< DMA Interrupt status register */
__IO uint32_t SRAMBASE; /*!< DMA SRAM address of the channel configuration table */
__I uint32_t RESERVED2[5];
LPC_DMA_COMMON_T DMACOMMON[1]; /*!< DMA shared channel (common) registers */
__I uint32_t RESERVED0[225];
LPC_DMA_CHANNEL_T DMACH[MAX_DMA_CHANNEL]; /*!< DMA channel registers */
} LPC_DMA_T;
/* Reserved bits masks... */
#define DMA_CTRL_RESERVED (~1)
#define DMA_INTSTAT_RESERVED (~7)
#define DMA_SRAMBASE_RESERVED (0xFF)
typedef enum {
WIDTH_8_BITS = 0,
WIDTH_16_BITS = 1,
WIDTH_32_BITS = 2
} DataWidth;
/**
* @brief Easy API, setup all required things to make DMA ready to use
* @param ch : DMA channel ID
* @return Nothing
*/
void ChipEz_DMA_Init(uint32_t isEnableIRQ);
/**
* @brief Easy API, setup the next transfer for a channel, this function updates DMA descriptor
* @param ch : DMA channel ID
* @param src_address: Source base address
* @param src_increment: Increment of source address after each transfer. Could be DMA_XFERCFG_SRCINC_0/1/2/4
* @param dst_address: Destination base address
* @param dst_increment: Increment of destination address after each transfer. Could be DMA_XFERCFG_DSTINC_0/1/2/4
* @param xfr_width: Width of transfer unit, could be WIDTH_8_BITS, WIDTH_16_BITS, or WIDTH_32_BITS
* @param length_bytes: Transfer length, in bytes. Must NOT makes transfer unit count exceed 1024.
* @param priority: Channel priority, used internally in DMA, could be from 0 (highest) to 7 (lowest)
* @return Nothing
* @note This function will set the DMA descriptor in the SRAM table to the
* the passed descriptor. This function is only meant to be used when
* the DMA channel is not active and can be used to setup the
* initial transfer for a linked list or ping-pong buffer or just a
* single transfer without a next descriptor.
*/
void ChipEz_DMA_InitChannel( DMA_CHID_T ch, uint32_t src_address, uint32_t src_increment,
uint32_t dst_address, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes, uint32_t priority);
/**
* @brief Easy API, Start transfer of a DMA channel
* @param ch : DMA channel ID
* @param src_increment: Increment of source address after each transfer. Could be DMA_XFERCFG_SRCINC_0/1/2/4.
* Should be consistent with the same parameter used in ChipEz_DMA_InitChannel()
* @param dst_increment: Increment of destination address after each transfer. Could be DMA_XFERCFG_DSTINC_0/1/2/4
* hould be consistent with the same parameter used in ChipEz_DMA_InitChannel()
* @param xfr_width: Width of transfer unit, could be WIDTH_8_BITS, WIDTH_16_BITS, or WIDTH_32_BITS
* Should be consistent with the same parameter used in ChipEz_DMA_InitChannel()
* @param length_bytes: Transfer length, in bytes. Must NOT makes transfer unit count exceed 1024.
* Should be consistent with the same parameter used in ChipEz_DMA_InitChannel()
* @param priority: Channel priority, used internally in DMA, could be from 0 (highest) to 7 (lowest)
* @return Nothing
*/
void ChipEz_DMA_StartTransfer(DMA_CHID_T ch, uint32_t src_increment, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes);
/**
* @brief Easier API, Combine ChipEz_DMA_InitChannel and ChipEz_DMA_StartTransfer with channel busy check
parameter is the same as ChipEz_DMA_InitChannel
@return TRUE when success, FALSE when current channel is busy.
*/
bool ChipEzr_DMA_Transfer( DMA_CHID_T channel, uint32_t src_address, uint32_t src_increment,
uint32_t dst_address, uint32_t dst_increment, uint32_t xfr_width, uint32_t length_bytes, uint32_t priority);
/**
* @brief Easy API, Abort a DMA channel safely
* @param ch : DMA channel ID
* @return Nothing
*/
void ChipEz_DMA_AbortChannel(DMA_CHID_T ch);
/** @defgroup DMA_COMMONDRV_8XX CHIP: LPC8xx DMA Controller driver common functions
* @{
*/
/**
* @brief Initialize DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Init(LPC_DMA_T *pDMA)
{
(void) pDMA;
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_DMA);
}
/**
* @brief De-Initialize DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DeInit(LPC_DMA_T *pDMA)
{
(void) pDMA;
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_DMA);
}
/**
* @brief Enable DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Enable(LPC_DMA_T *pDMA)
{
pDMA->CTRL = 1;
}
/**
* @brief Disable DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Disable(LPC_DMA_T *pDMA)
{
pDMA->CTRL = 0;
}
/* DMA interrupt status bits (common) */
#define DMA_INTSTAT_ACTIVEINT 0x2 /*!< Summarizes whether any enabled interrupts are pending */
#define DMA_INTSTAT_ACTIVEERRINT 0x4 /*!< Summarizes whether any error interrupts are pending */
/**
* @brief Get pending interrupt or error interrupts
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of DMA_INTSTAT_* types
* @note If any DMA channels have an active interrupt or error interrupt
* pending, this functional will a common status that applies to all
* channels.
*/
STATIC INLINE uint32_t Chip_DMA_GetIntStatus(LPC_DMA_T *pDMA)
{
return (pDMA->INTSTAT & ~DMA_INTSTAT_RESERVED);
}
/* DMA channel source/address/next descriptor */
typedef struct {
uint32_t xfercfg; /*!< Transfer configuration (only used in linked lists and ping-pong configs) */
uint32_t source; /*!< DMA transfer source end address */
uint32_t dest; /*!< DMA transfer desintation end address */
uint32_t next; /*!< Link to next DMA descriptor, must be 16 byte aligned */
} DMA_CHDESC_T;
/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase()
function if a DMA SRAM table is needed. */
extern DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL];
/**
* @brief Set DMA controller SRAM base address
* @param pDMA : The base of DMA controller on the chip
* @param base : The base address where the DMA descriptors will be stored
* @return Nothing
* @note A 256 byte block of memory aligned on a 256 byte boundary must be
* provided for this function. It sets the base address used for
* DMA descriptor table (16 descriptors total that use 16 bytes each).<br>
*
* A pre-defined table with correct alignment can be used for this
* function by calling Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
*/
STATIC INLINE void Chip_DMA_SetSRAMBase(LPC_DMA_T *pDMA, uint32_t base)
{
pDMA->SRAMBASE = base;
}
/**
* @brief Returns DMA controller SRAM base address
* @param pDMA : The base of DMA controller on the chip
* @return The base address where the DMA descriptors are stored
*/
STATIC INLINE uint32_t Chip_DMA_GetSRAMBase(LPC_DMA_T *pDMA)
{
return (pDMA->SRAMBASE & ~DMA_SRAMBASE_RESERVED);
}
/**
* @}
*/
/** @defgroup DMA_COMMON_8XX CHIP: LPC8xx DMA Controller driver common channel functions
* @{
*/
/**
* @brief Enables a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_EnableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ENABLESET = (1 << ch);
}
/**
* @brief Disables a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DisableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ENABLECLR = (1 << ch);
}
/**
* @brief Returns all enabled DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all enabled DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is enabled. A low state is disabled.
*/
STATIC INLINE uint32_t Chip_DMA_GetEnabledChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ENABLESET & ~DMA_ENABLESET_RESERVED);
}
/**
* @brief Returns all active DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all active DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is active. A low state is inactive. A active
* channel indicates that a DMA operation has been started but
* not yet fully completed.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ACTIVE & ~DMA_ACTIVE_RESERVED);
}
/**
* @brief Returns all busy DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all busy DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is busy. A low state is not busy. A DMA
* channel is considered busy when there is any operation
* related to that channel in the DMA controller<EFBFBD>s internal
* pipeline.
*/
STATIC INLINE uint32_t Chip_DMA_GetBusyChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].BUSY & ~DMA_BUSY_RESERVED);
}
/**
* @brief Returns pending error interrupt status for all DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all channels (0 - 15) error interrupt status
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has a pending error interrupt. A low state
* indicates no error interrupt.
*/
STATIC INLINE uint32_t Chip_DMA_GetErrorIntChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ERRINT & ~DMA_ERRINT_RESERVED);
}
/**
* @brief Clears a pending error interrupt status for a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearErrorIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ERRINT = (1 << ch);
}
/**
* @brief Enables a single DMA channel's interrupt used in common DMA interrupt
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_EnableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTENSET = (1 << ch);
}
/**
* @brief Disables a single DMA channel's interrupt used in common DMA interrupt
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DisableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTENCLR = (1 << ch);
}
/**
* @brief Returns all enabled interrupt channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an enabled interrupt for the channel.
* A low state indicates that the DMA channel will not contribute
* to the common DMA interrupt status.
*/
STATIC INLINE uint32_t Chip_DMA_GetEnableIntChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTENSET & ~DMA_INTENSET_RESERVED);
}
/**
* @brief Returns active A interrupt status for all channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an active A interrupt for the channel.
* A low state indicates that the A interrupt is not active.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveIntAChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTA & ~DMA_INTA_RESERVED);
}
/**
* @brief Clears active A interrupt status for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearActiveIntAChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTA = (1 << ch);
}
/**
* @brief Returns active B interrupt status for all channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an active B interrupt for the channel.
* A low state indicates that the B interrupt is not active.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveIntBChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTB & ~DMA_INTB_RESERVED);
}
/**
* @brief Clears active B interrupt status for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearActiveIntBChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTB = (1 << ch);
}
/**
* @brief Sets the VALIDPENDING control bit for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note See the User Manual for more information for what this bit does.
*
*/
STATIC INLINE void Chip_DMA_SetValidChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].SETVALID = (1 << ch);
}
/**
* @brief Sets the TRIG bit for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note See the User Manual for more information for what this bit does.
*/
STATIC INLINE void Chip_DMA_SetTrigChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].SETTRIG = (1 << ch);
}
/**
* @brief Aborts a DMA operation for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note To abort a channel, the channel should first be disabled. Then wait
* until the channel is no longer busy by checking the corresponding
* bit in BUSY. Finally, abort the channel operation. This prevents the
* channel from restarting an incomplete operation when it is enabled
* again.
*/
STATIC INLINE void Chip_DMA_AbortChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ABORT = (1 << ch);
}
/**
* @}
*/
/** @defgroup DMA_CHANNEL_8XX CHIP: LPC8xx DMA Controller driver channel specific functions
* @{
*/
/* Support macro for DMA_CHDESC_T */
#define DMA_ADDR(addr) ((uint32_t) (addr))
/* Support definitions for setting the configuration of a DMA channel. You
will need to get more information on these options from the User manual. */
#define DMA_CFG_PERIPHREQEN (1 << 0) /*!< Enables Peripheral DMA requests */
#define DMA_CFG_HWTRIGEN (1 << 1) /*!< Use hardware triggering via imput mux */
#define DMA_CFG_TRIGPOL_LOW (0 << 4) /*!< Hardware trigger is active low or falling edge */
#define DMA_CFG_TRIGPOL_HIGH (1 << 4) /*!< Hardware trigger is active high or rising edge */
#define DMA_CFG_TRIGTYPE_EDGE (0 << 5) /*!< Hardware trigger is edge triggered */
#define DMA_CFG_TRIGTYPE_LEVEL (1 << 5) /*!< Hardware trigger is level triggered */
#define DMA_CFG_TRIGBURST_SNGL (0 << 6) /*!< Single transfer. Hardware trigger causes a single transfer */
#define DMA_CFG_TRIGBURST_BURST (1 << 6) /*!< Burst transfer (see UM) */
#define DMA_CFG_BURSTPOWER_1 (0 << 8) /*!< Set DMA burst size to 1 transfer */
#define DMA_CFG_BURSTPOWER_2 (1 << 8) /*!< Set DMA burst size to 2 transfers */
#define DMA_CFG_BURSTPOWER_4 (2 << 8) /*!< Set DMA burst size to 4 transfers */
#define DMA_CFG_BURSTPOWER_8 (3 << 8) /*!< Set DMA burst size to 8 transfers */
#define DMA_CFG_BURSTPOWER_16 (4 << 8) /*!< Set DMA burst size to 16 transfers */
#define DMA_CFG_BURSTPOWER_32 (5 << 8) /*!< Set DMA burst size to 32 transfers */
#define DMA_CFG_BURSTPOWER_64 (6 << 8) /*!< Set DMA burst size to 64 transfers */
#define DMA_CFG_BURSTPOWER_128 (7 << 8) /*!< Set DMA burst size to 128 transfers */
#define DMA_CFG_BURSTPOWER_256 (8 << 8) /*!< Set DMA burst size to 256 transfers */
#define DMA_CFG_BURSTPOWER_512 (9 << 8) /*!< Set DMA burst size to 512 transfers */
#define DMA_CFG_BURSTPOWER_1024 (10 << 8) /*!< Set DMA burst size to 1024 transfers */
#define DMA_CFG_BURSTPOWER(n) ((n) << 8) /*!< Set DMA burst size to 2^n transfers, max n=10 */
#define DMA_CFG_SRCBURSTWRAP (1 << 14) /*!< Source burst wrapping is enabled for this DMA channel */
#define DMA_CFG_DSTBURSTWRAP (1 << 15) /*!< Destination burst wrapping is enabled for this DMA channel */
#define DMA_CFG_CHPRIORITY(p) ((p) << 16) /*!< Sets DMA channel priority, min 0 (highest), max 3 (lowest) */
/**
* @brief Setup a DMA channel configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param cfg : An Or'ed value of DMA_CFG_* values that define the channel's configuration
* @return Nothing
* @note This function sets up all configurable options for the DMA channel.
* These options are usually set once for a channel and then unchanged.<br>
*
* The following example show how to configure the channel for peripheral
* DMA requests, burst transfer size of 1 (in 'transfers', not bytes),
* continuous reading of the same source address, incrementing destination
* address, and highest channel priority.<br>
* Example: Chip_DMA_SetupChannelConfig(pDMA, SSP0_RX_DMA,
* (DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_1 |
* DMA_CFG_SRCBURSTWRAP | DMA_CFG_CHPRIORITY(0)));<br>
*
* The following example show how to configure the channel for an external
* trigger from the imput mux with low edge polarity, a burst transfer size of 8,
* incrementing source and destination addresses, and lowest channel
* priority.<br>
* Example: Chip_DMA_SetupChannelConfig(pDMA, DMA_CH14,
* (DMA_CFG_HWTRIGEN | DMA_CFG_TRIGPOL_LOW | DMA_CFG_TRIGTYPE_EDGE |
* DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_8 |
* DMA_CFG_CHPRIORITY(3)));<br>
*
* For non-peripheral DMA triggering (DMA_CFG_HWTRIGEN definition), use the
* DMA input mux functions to configure the DMA trigger source for a DMA channel.
*/
STATIC INLINE void Chip_DMA_SetupChannelConfig(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg)
{
pDMA->DMACH[ch].CFG = cfg;
}
/* DMA channel control and status register definitions */
#define DMA_CTLSTAT_VALIDPENDING (1 << 0) /*!< Valid pending flag for this channel */
#define DMA_CTLSTAT_TRIG (1 << 2) /*!< Trigger flag. Indicates that the trigger for this channel is currently set */
/**
* @brief Returns channel specific status flags
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return AN Or'ed value of DMA_CTLSTAT_VALIDPENDING and DMA_CTLSTAT_TRIG
*/
STATIC INLINE uint32_t Chip_DMA_GetChannelStatus(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
return (pDMA->DMACH[ch].XFERCFG & ~DMA_XFERCFG_RESERVED);
}
/* DMA channel transfer configuration registers definitions */
#define DMA_XFERCFG_CFGVALID (1 << 0) /*!< Configuration Valid flag */
#define DMA_XFERCFG_RELOAD (1 << 1) /*!< Indicates whether the channels control structure will be reloaded when the current descriptor is exhausted */
#define DMA_XFERCFG_SWTRIG (1 << 2) /*!< Software Trigger */
#define DMA_XFERCFG_CLRTRIG (1 << 3) /*!< Clear Trigger */
#define DMA_XFERCFG_SETINTA (1 << 4) /*!< Set Interrupt flag A for this channel to fire when descriptor is complete */
#define DMA_XFERCFG_SETINTB (1 << 5) /*!< Set Interrupt flag B for this channel to fire when descriptor is complete */
#define DMA_XFERCFG_WIDTH_8 (0 << 8) /*!< 8-bit transfers are performed */
#define DMA_XFERCFG_WIDTH_16 (1 << 8) /*!< 16-bit transfers are performed */
#define DMA_XFERCFG_WIDTH_32 (2 << 8) /*!< 32-bit transfers are performed */
#define DMA_XFERCFG_SRCINC_0 (0 << 12) /*!< DMA source address is not incremented after a transfer */
#define DMA_XFERCFG_SRCINC_1 (1 << 12) /*!< DMA source address is incremented by 1 (width) after a transfer */
#define DMA_XFERCFG_SRCINC_2 (2 << 12) /*!< DMA source address is incremented by 2 (width) after a transfer */
#define DMA_XFERCFG_SRCINC_4 (3 << 12) /*!< DMA source address is incremented by 4 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_0 (0 << 14) /*!< DMA destination address is not incremented after a transfer */
#define DMA_XFERCFG_DSTINC_1 (1 << 14) /*!< DMA destination address is incremented by 1 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_2 (2 << 14) /*!< DMA destination address is incremented by 2 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_4 (3 << 14) /*!< DMA destination address is incremented by 4 (width) after a transfer */
#define DMA_XFERCFG_XFERCOUNT(n) ((n - 1) << 16) /*!< DMA transfer count in 'transfers', between (0)1 and (1023)1024 */
/**
* @brief Setup a DMA channel transfer configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param cfg : An Or'ed value of DMA_XFERCFG_* values that define the channel's transfer configuration
* @return Nothing
* @note This function sets up the transfer configuration for the DMA channel.<br>
*
* The following example show how to configure the channel's transfer for
* multiple transfer descriptors (ie, ping-pong), interrupt 'A' trigger on
* transfer descriptor completion, 128 byte size transfers, and source and
* destination address increment.<br>
* Example: Chip_DMA_SetupChannelTransfer(pDMA, SSP0_RX_DMA,
* (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_RELOAD | DMA_XFERCFG_SETINTA |
* DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_1 |
* DMA_XFERCFG_XFERCOUNT(128)));<br>
*/
STATIC INLINE void Chip_DMA_SetupChannelTransfer(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg)
{
pDMA->DMACH[ch].XFERCFG = cfg;
}
/**
* @brief Set DMA transfer register interrupt bits (safe)
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param mask : Bits to set
* @return Nothing
* @note This function safely sets bits in the DMA channel specific XFERCFG
* register.
*/
STATIC INLINE void Chip_DMA_SetTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
{
/* Read and write values may not be the same, write 0 to
undefined bits */
pDMA->DMACH[ch].XFERCFG = (pDMA->DMACH[ch].XFERCFG & ~DMA_XFERCFG_RESERVED) | mask;
}
/**
* @brief Clear DMA transfer register interrupt bits (safe)
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param mask : Bits to clear
* @return Nothing
* @note This function safely clears bits in the DMA channel specific XFERCFG
* register.
*/
STATIC INLINE void Chip_DMA_ClearTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
{
/* Read and write values may not be the same, write 0 to
undefined bits */
pDMA->DMACH[ch].XFERCFG &= ~(DMA_XFERCFG_RESERVED | mask);
}
/**
* @brief Update the transfer size in an existing DMA channel transfer configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param trans : Number of transfers to update the transfer configuration to (1 - 1023)
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetupChannelTransferSize(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t trans)
{
pDMA->DMACH[ch].XFERCFG = (pDMA->DMACH[ch].XFERCFG & ~(DMA_XFERCFG_RESERVED | (0x3FF << 16))) | DMA_XFERCFG_XFERCOUNT(trans);
}
/**
* @brief Sets a DMA channel configuration as valid
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetChannelValid(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID);
}
/**
* @brief Sets a DMA channel configuration as invalid
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetChannelInValid(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_ClearTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID);
}
/**
* @brief Performs a software trigger of the DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SWTriggerChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_SWTRIG);
}
/**
* @brief Checks if the given channel is active or not
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return 1 if channel @a ch is active; 0 if channel @a ch is not active
*/
STATIC INLINE bool Chip_DMA_IsChannelActive(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
return (pDMA->DMACOMMON[0].ACTIVE & (1 << ch)) != 0;
}
/**
* @brief Sets up a DMA channel with the passed DMA transfer descriptor
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param desc : Pointer to DMA transfer descriptor
* @return false if the DMA channel was active, otherwise true
* @note This function will set the DMA descriptor in the SRAM table to the
* the passed descriptor. This function is only meant to be used when
* the DMA channel is not active and can be used to setup the
* initial transfer for a linked list or ping-pong buffer or just a
* single transfer without a next descriptor.<br>
*
* If using this function to write the initial transfer descriptor in
* a linked list or ping-pong buffer configuration, it should contain a
* non-NULL 'next' field pointer.
*/
STATIC INLINE bool Chip_DMA_SetupTranChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch, const DMA_CHDESC_T *desc)
{
/* If channel is active return false */
if (Chip_DMA_IsChannelActive(pDMA, ch))
return false;
/* Assign the descriptor to descriptor table */
((DMA_CHDESC_T *) (pDMA->SRAMBASE & ~DMA_SRAMBASE_RESERVED))[ch] = *desc;
return true;
}
/**
* @}
*/
#endif /* __DMA_8XX_H_ */

View File

@ -0,0 +1,61 @@
/*
* @brief LPC8xx GPIO driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#include "gpio_8xx.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
///* GPIO initilisation function */
//void Chip_GPIO_Init(LPC_GPIO_T *pGPIO)
//{
// Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO);
//}
///* GPIO deinitialisation function */
//void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO)
//{
// Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO);
//}

View File

@ -0,0 +1,357 @@
/*
* @brief LPC8xx GPIO driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __GPIO_8XX_H_
#define __GPIO_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup GPIO_8XX CHIP: LPC8xx GPIO driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief GPIO port register block structure
*/
typedef struct { /*!< GPIO_PORT Structure */
__IO uint8_t B[128][32]; /*!< Offset 0x0000: Byte pin registers ports 0 to n; pins PIOn_0 to PIOn_31 */
__IO uint32_t W[32][32]; /*!< Offset 0x1000: Word pin registers port 0 to n */
__IO uint32_t DIR[32]; /*!< Offset 0x2000: Direction registers port n */
__IO uint32_t MASK[32]; /*!< Offset 0x2080: Mask register port n */
__IO uint32_t PIN[32]; /*!< Offset 0x2100: Portpin register port n */
__IO uint32_t MPIN[32]; /*!< Offset 0x2180: Masked port register port n */
__IO uint32_t SET[32]; /*!< Offset 0x2200: Write: Set register for port n Read: output bits for port n */
__O uint32_t CLR[32]; /*!< Offset 0x2280: Clear port n */
__O uint32_t NOT[32]; /*!< Offset 0x2300: Toggle port n */
__O uint32_t DIRSET[32]; /*!< Offset 0x2380: Set Direction */
__O uint32_t DIRCLR[32]; /*!< Offset 0x2400: Clear Direction */
__O uint32_t DIRNOT[32]; /*!< Offset 0x2480: Toggle Dirction */
} LPC_GPIO_T;
/**
* @brief Initialize GPIO block
* @param pGPIO : The base of GPIO peripheral on the chip
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_Init(LPC_GPIO_T *pGPIO)
{
LPC_SYSCTL->SYSAHBCLKCTRL = (1 << SYSCTL_CLOCK_GPIO) | (LPC_SYSCTL->SYSAHBCLKCTRL & ~SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief De-Initialize GPIO block
* @param pGPIO : The base of GPIO peripheral on the chip
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO)
{
LPC_SYSCTL->SYSAHBCLKCTRL &= ~((1 << SYSCTL_CLOCK_GPIO) | SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief Set GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set direction on as output
* @param isOutput: If new direction is output
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_PinSetDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool isOutput)
{
#ifdef CHIP_LPC82X
if (isOutput)
pGPIO->DIRSET[port] = 1UL << pin;
else
pGPIO->DIRCLR[port] = 1UL << pin;
#else
if (isOutput)
pGPIO->DIR[port] |= 1UL << pin;
else
pGPIO->DIR[port] &= ~(1UL << pin);
#endif
}
/**
* @brief Get GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to get direction for
* @return true if the GPIO is an output, false if input
*/
STATIC INLINE bool Chip_GPIO_PinGetDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
return (bool) (((pGPIO->DIR[port]) >> pin) & 1);
}
/**
* @brief Toggle GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to toggle direction
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_PinToggleDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
#ifdef CHIP_LPC82X
pGPIO->DIRNOT[port] = 1UL << pin;
#else
pGPIO->DIR[port] ^= 1UL << pin;
#endif
}
/**
* @brief Set a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set
* @param setting : true for high, false for low
* @return Nothing
* @note This function replaces Chip_GPIO_WritePortBit()
*/
STATIC INLINE void Chip_GPIO_PinSetState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool setting)
{
pGPIO->B[port][pin] = setting;
}
/**
* @brief Get a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to get state for
* @return true if the GPIO is high, false if low
* @note This function replaces Chip_GPIO_ReadPortBit()
*/
STATIC INLINE bool Chip_GPIO_PinGetState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
return (bool) pGPIO->B[port][pin];
}
/**
* @brief Get a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to get state for
* @return true if the GPIO is high, false if low
* @note This function replaces Chip_GPIO_ReadPortBit()
*/
STATIC INLINE void Chip_GPIO_PinToggleState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
pGPIO->NOT[port] = 1UL << pin;
}
/**
* @brief Set GPIO direction for a all selected GPIO pins
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask to set direction on as output (bits 0..b for pins 0..n)
* @param isOutput: If new direction is output
* @return Nothing
* @note Sets multiple GPIO pins to the output direction, each bit's position that is
* high sets the corresponding pin number for that bit to an output.
*/
STATIC INLINE void Chip_GPIO_PortSetDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask, bool isOutput)
{
#ifdef CHIP_LPC82X
if (isOutput)
pGPIO->DIRSET[port] = pinMask;
else
pGPIO->DIRCLR[port] = pinMask;
#else
if (isOutput)
pGPIO->DIR[port] |= pinMask;
else
pGPIO->DIR[port] &= ~pinMask;
#endif
}
/**
* @brief Get GPIO direction for a all GPIO pins
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return a bitfield containing the input and output states for each pin
* @note For pins 0..n, a high state in a bit corresponds to an output state for the
* same pin, while a low state corresponds to an input state.
*/
STATIC INLINE uint32_t Chip_GPIO_PortGetDIR(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->DIR[port];
}
/**
* @brief Toggle GPIO direction for a all selected GPIO pins
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask Toggle direction (bits 0..n for pins 0..n)
* @return Nothing
* @note Toggles multiple GPIO pin's direction, each bit's position that is
* high toggles direction of the corresponding pin number.
*/
STATIC INLINE void Chip_GPIO_PortToggleDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask)
{
#ifdef CHIP_LPC82X
pGPIO->DIRNOT[port] = pinMask;
#else
pGPIO->DIR[port] ^= pinMask;
#endif
}
/**
* @brief Set all GPIO raw pin states (regardless of masking)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param value : Value to set all GPIO pin states (0..n) to
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_PortSetState(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value)
{
pGPIO->PIN[port] = value;
}
/**
* @brief Get all GPIO raw pin states (regardless of masking)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Current (raw) state of all GPIO pins
*/
STATIC INLINE uint32_t Chip_GPIO_PortGetState(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->PIN[port];
}
/**
* @brief Toggle selected GPIO output pins to the opposite state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to toggle
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_PortToggleState(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins)
{
pGPIO->NOT[port] = pins;
}
/**
* @brief Set selected GPIO output pins to the high state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to set high
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_PortSetOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t bmPins)
{
pGPIO->SET[port] = bmPins;
}
/**
* @brief Set selected GPIO output pins to the low state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to set low
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_PortSetOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins)
{
pGPIO->CLR[port] = pins;
}
/**
* @brief Set GPIO port mask value for GPIO masked read and write
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param mask : Mask value for read and write (only low bits are enabled)
* @return Nothing
* @note Controls which bits are set or unset when using the masked
* GPIO read and write functions. A low state indicates the pin is settable
* and readable via the masked write and read functions.
*/
STATIC INLINE void Chip_GPIO_PortSetMask(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t mask)
{
pGPIO->MASK[port] = mask;
}
/**
* @brief Get GPIO port mask value used for GPIO masked read and write
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Returns value set with the Chip_GPIO_PortSetMask() function.
* @note A high bit in the return value indicates that that GPIO pin for the
* port cannot be set using the masked write function.
*/
STATIC INLINE uint32_t Chip_GPIO_PortGetMask(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->MASK[port];
}
/**
* @brief Set all GPIO pin states, but mask via the MASKP0 register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param value : Value to set all GPIO pin states (0..n) to
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_PortSetMaskedState(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value)
{
pGPIO->MPIN[port] = value;
}
/**
* @brief Get all GPIO pin statesm but mask via the MASKP0 register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Current (masked) state of all GPIO pins
*/
STATIC INLINE uint32_t Chip_GPIO_PortGetMaskedState(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->MPIN[port];
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __GPIO_8XX_H_ */

View File

@ -0,0 +1,307 @@
/*
* @brief LPC15xx I2C Common driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/* Get the RESET ID corresponding to the given I2C base */
static CHIP_SYSCTL_PERIPH_RESET_T I2C_GetResetID(LPC_I2C_T *pI2C)
{
uint32_t base = (uint32_t) pI2C;
switch (base) {
case LPC_I2C1_BASE:
return RESET_I2C1;
case LPC_I2C2_BASE:
return RESET_I2C2;
case LPC_I2C3_BASE:
return RESET_I2C3;
default:
return RESET_I2C0;
}
}
/* Get the CLOCK ID corresponding to the given I2C base */
static CHIP_SYSCTL_CLOCK_T I2C_GetClockID(LPC_I2C_T *pI2C)
{
uint32_t base = (uint32_t) pI2C;
switch (base) {
case LPC_I2C1_BASE:
return SYSCTL_CLOCK_I2C1;
case LPC_I2C2_BASE:
return SYSCTL_CLOCK_I2C2;
case LPC_I2C3_BASE:
return SYSCTL_CLOCK_I2C3;
default:
return SYSCTL_CLOCK_I2C0;
}
}
/**
* @brief Sets HIGH and LOW duty cycle registers
* @param pI2C : Pointer to selected I2C peripheral
* @param sclH : Number of I2C_PCLK cycles for the SCL HIGH time value between (2 - 9).
* @param sclL : Number of I2C_PCLK cycles for the SCL LOW time value between (2 - 9).
* @return Nothing
* @note The I2C clock divider should be set to the appropriate value before calling this function
* The I2C baud is determined by the following formula: <br>
* I2C_bitFrequency = (I2C_PCLK)/(I2C_CLKDIV * (sclH + sclL)) <br>
* where I2C_PCLK is the frequency of the System clock and I2C_CLKDIV is I2C clock divider
*/
static void Chip_I2CM_SetDutyCycle(LPC_I2C_T *pI2C, uint16_t sclH, uint16_t sclL)
{
/* Limit to usable range of timing values */
if (sclH < 2) {
sclH = 2;
}
else if (sclH > 9) {
sclH = 9;
}
if (sclL < 2) {
sclL = 2;
}
else if (sclL > 9) {
sclL = 9;
}
pI2C->MSTTIME = (((sclH - 2) & 0x07) << 4) | ((sclL - 2) & 0x07);
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initializes the LPC_I2C peripheral */
void Chip_I2C_Init(LPC_I2C_T *pI2C)
{
/* Enable I2C clock */
Chip_Clock_EnablePeriphClock(I2C_GetClockID(pI2C));
/* Peripheral reset control to I2C */
Chip_SYSCTL_PeriphReset(I2C_GetResetID(pI2C));
}
/* Shuts down the I2C controller block */
void Chip_I2C_DeInit(LPC_I2C_T *pI2C)
{
/* Disable I2C clock */
Chip_Clock_DisablePeriphClock(I2C_GetClockID(pI2C));
}
/* Set up bus speed for LPC_I2C interface */
void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed)
{
uint32_t scl = Chip_Clock_GetSystemClockRate() / (Chip_I2C_GetClockDiv(pI2C) * busSpeed);
Chip_I2CM_SetDutyCycle(pI2C, (scl >> 1), (scl - (scl >> 1)));
}
/* Master transfer state change handler handler */
uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
uint32_t status = Chip_I2CM_GetStatus(pI2C);
/* Master Lost Arbitration */
if (status & I2C_STAT_MSTRARBLOSS) {
/* Set transfer status as Arbitration Lost */
xfer->status = I2CM_STATUS_ARBLOST;
/* Clear Status Flags */
Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTRARBLOSS);
}
/* Master Start Stop Error */
else if (status & I2C_STAT_MSTSTSTPERR) {
/* Set transfer status as Bus Error */
xfer->status = I2CM_STATUS_BUS_ERROR;
/* Clear Status Flags */
Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTSTSTPERR);
}
/* Master is Pending */
else if (status & I2C_STAT_MSTPENDING) {
/* Branch based on Master State Code */
switch (Chip_I2CM_GetMasterState(pI2C)) {
/* Master idle */
case I2C_STAT_MSTCODE_IDLE:
/* Do Nothing */
break;
/* Receive data is available */
case I2C_STAT_MSTCODE_RXREADY:
/* Read Data */
*xfer->rxBuff++ = pI2C->MSTDAT;
xfer->rxSz--;
if (xfer->rxSz) {
/* Set Continue if there is more data to read */
Chip_I2CM_MasterContinue(pI2C);
}
else {
/* Set transfer status as OK */
xfer->status = I2CM_STATUS_OK;
/* No data to read send Stop */
Chip_I2CM_SendStop(pI2C);
}
break;
/* Master Transmit available */
case I2C_STAT_MSTCODE_TXREADY:
if (xfer->txSz) {
/* If Tx data available transmit data and continue */
pI2C->MSTDAT = *xfer->txBuff++;
xfer->txSz--;
Chip_I2CM_MasterContinue(pI2C);
}
else {
/* If receive queued after transmit then initiate master receive transfer*/
if (xfer->rxSz) {
/* Write Address and RW bit to data register */
Chip_I2CM_WriteByte(pI2C, (xfer->slaveAddr << 1) | 0x1);
/* Enter to Master Transmitter mode */
Chip_I2CM_SendStart(pI2C);
}
else {
/* If no receive queued then set transfer status as OK */
xfer->status = I2CM_STATUS_OK;
/* Send Stop */
Chip_I2CM_SendStop(pI2C);
}
}
break;
case I2C_STAT_MSTCODE_NACKADR:
/* Set transfer status as NACK on address */
xfer->status = I2CM_STATUS_NAK_ADR;
Chip_I2CM_SendStop(pI2C);
break;
case I2C_STAT_MSTCODE_NACKDAT:
/* Set transfer status as NACK on data */
xfer->status = I2CM_STATUS_NAK_DAT;
Chip_I2CM_SendStop(pI2C);
break;
default:
/* Default case should not occur*/
xfer->status = I2CM_STATUS_ERROR;
break;
}
}
else {
/* Default case should not occur */
xfer->status = I2CM_STATUS_ERROR;
}
return xfer->status != I2CM_STATUS_BUSY;
}
/* Transmit and Receive data in master mode */
void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
/* set the transfer status as busy */
xfer->status = I2CM_STATUS_BUSY;
/* Clear controller state. */
Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR);
/* Write Address and RW bit to data register */
Chip_I2CM_WriteByte(pI2C, (xfer->slaveAddr << 1) | (xfer->txSz == 0));
/* Enter to Master Transmitter mode */
Chip_I2CM_SendStart(pI2C);
}
/* Transmit and Receive data in master mode */
uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
uint32_t ret = 0;
/* start transfer */
Chip_I2CM_Xfer(pI2C, xfer);
while (ret == 0) {
/* wait for status change interrupt */
while (!Chip_I2CM_IsMasterPending(pI2C)) {}
/* call state change handler */
ret = Chip_I2CM_XferHandler(pI2C, xfer);
}
return ret;
}
/* Slave transfer state change handler */
uint32_t Chip_I2CS_XferHandler(LPC_I2C_T *pI2C, const I2CS_XFER_T *xfers)
{
uint32_t done = 0;
uint8_t data;
uint32_t state;
/* transfer complete? */
if ((Chip_I2C_GetPendingInt(pI2C) & I2C_INTENSET_SLVDESEL) != 0) {
Chip_I2CS_ClearStatus(pI2C, I2C_STAT_SLVDESEL);
xfers->slaveDone();
}
else {
/* Determine the current I2C slave state */
state = Chip_I2CS_GetSlaveState(pI2C);
switch (state) {
case I2C_STAT_SLVCODE_ADDR: /* Slave address received */
/* Get slave address that needs servicing */
data = Chip_I2CS_GetSlaveAddr(pI2C, Chip_I2CS_GetSlaveMatchIndex(pI2C));
/* Call address callback */
xfers->slaveStart(data);
break;
case I2C_STAT_SLVCODE_RX: /* Data byte received */
/* Get received data */
data = Chip_I2CS_ReadByte(pI2C);
done = xfers->slaveRecv(data);
break;
case I2C_STAT_SLVCODE_TX: /* Get byte that needs to be sent */
/* Get data to send */
done = xfers->slaveSend(&data);
Chip_I2CS_WriteByte(pI2C, data);
break;
}
}
if (done == 0) {
Chip_I2CS_SlaveContinue(pI2C);
}
else {
Chip_I2CS_SlaveNACK(pI2C);
}
return done;
}

View File

@ -0,0 +1,890 @@
/*
* @brief LPC15xx I2C driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __I2C_COMMON_8XX_H_
#define __I2C_COMMON_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup I2C_15XX CHIP: LPC15xx I2C driver
* @ingroup CHIP_15XX_Drivers
* @{
*/
/**
* @brief I2C register block structure
*/
typedef struct { /* I2C0 Structure */
__IO uint32_t CFG; /*!< I2C Configuration Register common for Master, Slave and Monitor */
__IO uint32_t STAT; /*!< I2C Status Register common for Master, Slave and Monitor */
__IO uint32_t INTENSET; /*!< I2C Interrupt Enable Set Register common for Master, Slave and Monitor */
__O uint32_t INTENCLR; /*!< I2C Interrupt Enable Clear Register common for Master, Slave and Monitor */
__IO uint32_t TIMEOUT; /*!< I2C Timeout value Register */
__IO uint32_t CLKDIV; /*!< I2C Clock Divider Register */
__I uint32_t INTSTAT; /*!< I2C Interrupt Status Register */
__I uint32_t RESERVED0;
__IO uint32_t MSTCTL; /*!< I2C Master Control Register */
__IO uint32_t MSTTIME; /*!< I2C Master Time Register for SCL */
__IO uint32_t MSTDAT; /*!< I2C Master Data Register */
__I uint32_t RESERVED1[5];
__IO uint32_t SLVCTL; /*!< I2C Slave Control Register */
__IO uint32_t SLVDAT; /*!< I2C Slave Data Register */
__IO uint32_t SLVADR[4]; /*!< I2C Slave Address Registers */
__IO uint32_t SLVQUAL0; /*!< I2C Slave Address Qualifier 0 Register */
__I uint32_t RESERVED2[9];
__I uint32_t MONRXDAT; /*!< I2C Monitor Data Register */
} LPC_I2C_T;
/* Reserved bits masks for registers */
#define I2C_CFG_RESERVED (~0x1f)
#define I2C_STAT_RESERVED ((1<<5)|(1<<7)|(0xf<<20)|(0x3fu<<26))
#define I2C_INTENSET_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_INTENCLR_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_TIMEOUT_RESERVED 0xffff0000
#define I2C_CLKDIV_RESERVED 0xffff0000
#define I2C_INTSTAT_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_MSTCTL_RESERVED (~7)
#define I2C_MSTTIME_RESERVED (~0x7f)
#define I2C_MSTDAT_RESERVED (~0xff)
#define I2C_SLVCTL_RESERVED (~3)
#define I2C_SLVDAT_RESERVED (~0xff)
#define I2C_SLVADR_RESERVED (~0xff)
#define I2C_SLVQUAL0_RESERVED (~0xff)
/*
* @brief I2C Configuration register Bit definition
*/
#define I2C_CFG_MSTEN (1 << 0) /*!< Master Enable/Disable Bit */
#define I2C_CFG_SLVEN (1 << 1) /*!< Slave Enable/Disable Bit */
#define I2C_CFG_MONEN (1 << 2) /*!< Monitor Enable/Disable Bit */
#define I2C_CFG_TIMEOUTEN (1 << 3) /*!< Timeout Enable/Disable Bit */
#define I2C_CFG_MONCLKSTR (1 << 4) /*!< Monitor Clock Stretching Bit */
#define I2C_CFG_MASK ((uint32_t) 0x1F) /*!< Configuration register Mask */
/*
* @brief I2C Status register Bit definition
*/
#define I2C_STAT_MSTPENDING (1 << 0) /*!< Master Pending Status Bit */
#define I2C_STAT_MSTSTATE (0x7 << 1) /*!< Master State Code */
#define I2C_STAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Bit */
#define I2C_STAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Bit */
#define I2C_STAT_SLVPENDING (1 << 8) /*!< Slave Pending Status Bit */
#define I2C_STAT_SLVSTATE (0x3 << 9) /*!< Slave State Code */
#define I2C_STAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Bit */
#define I2C_STAT_SLVIDX (0x3 << 12) /*!< Slave Address Index */
#define I2C_STAT_SLVSEL (1 << 14) /*!< Slave Selected Bit */
#define I2C_STAT_SLVDESEL (1 << 15) /*!< Slave Deselect Bit */
#define I2C_STAT_MONRDY (1 << 16) /*!< Monitor Ready Bit */
#define I2C_STAT_MONOV (1 << 17) /*!< Monitor Overflow Flag */
#define I2C_STAT_MONACTIVE (1 << 18) /*!< Monitor Active Flag */
#define I2C_STAT_MONIDLE (1 << 19) /*!< Monitor Idle Flag */
#define I2C_STAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Flag */
#define I2C_STAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Flag */
#define I2C_STAT_MSTCODE_IDLE (0) /*!< Master Idle State Code */
#define I2C_STAT_MSTCODE_RXREADY (1) /*!< Master Receive Ready State Code */
#define I2C_STAT_MSTCODE_TXREADY (2) /*!< Master Transmit Ready State Code */
#define I2C_STAT_MSTCODE_NACKADR (3) /*!< Master NACK by slave on address State Code */
#define I2C_STAT_MSTCODE_NACKDAT (4) /*!< Master NACK by slave on data State Code */
#define I2C_STAT_SLVCODE_ADDR (0) /*!< Master Idle State Code */
#define I2C_STAT_SLVCODE_RX (1) /*!< Received data is available Code */
#define I2C_STAT_SLVCODE_TX (2) /*!< Data can be transmitted Code */
/*
* @brief I2C Interrupt Enable Set register Bit definition
*/
#define I2C_INTENSET_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Enable Bit */
#define I2C_INTENSET_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Enable Bit */
#define I2C_INTENSET_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Enable Bit */
#define I2C_INTENSET_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Enable Bit */
#define I2C_INTENSET_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Enable Bit */
#define I2C_INTENSET_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Enable Bit */
#define I2C_INTENSET_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Enable Bit */
#define I2C_INTENSET_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Enable Bit */
#define I2C_INTENSET_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Enable Bit */
#define I2C_INTENSET_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Enable Bit */
#define I2C_INTENSET_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Enable Bit */
/*
* @brief I2C Interrupt Enable Clear register Bit definition
*/
#define I2C_INTENCLR_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Clear Bit */
#define I2C_INTENCLR_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Clear Bit */
#define I2C_INTENCLR_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Clear Bit */
#define I2C_INTENCLR_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Clear Bit */
#define I2C_INTENCLR_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Clear Bit */
#define I2C_INTENCLR_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Clear Bit */
#define I2C_INTENCLR_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Clear Bit */
#define I2C_INTENCLR_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Clear Bit */
#define I2C_INTENCLR_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Clear Bit */
#define I2C_INTENCLR_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Clear Bit */
#define I2C_INTENCLR_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Clear Bit */
/*
* @brief I2C TimeOut Value Macro
*/
#define I2C_TIMEOUT_VAL(n) (((uint32_t) ((n) - 1) & 0xFFF0) | 0x000F) /*!< Macro for Timeout value register */
/*
* @brief I2C Interrupt Status register Bit definition
*/
#define I2C_INTSTAT_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Status Bit */
#define I2C_INTSTAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Status Bit */
#define I2C_INTSTAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Status Bit */
#define I2C_INTSTAT_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Status Bit */
#define I2C_INTSTAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Status Bit */
#define I2C_INTSTAT_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Status Bit */
#define I2C_INTSTAT_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Status Bit */
#define I2C_INTSTAT_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Status Bit */
#define I2C_INTSTAT_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Status Bit */
#define I2C_INTSTAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Status Bit */
#define I2C_INTSTAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Status Bit */
/*
* @brief I2C Master Control register Bit definition
*/
#define I2C_MSTCTL_MSTCONTINUE (1 << 0) /*!< Master Continue Bit */
#define I2C_MSTCTL_MSTSTART (1 << 1) /*!< Master Start Control Bit */
#define I2C_MSTCTL_MSTSTOP (1 << 2) /*!< Master Stop Control Bit */
#define I2C_MSTCTL_MSTDMA (1 << 3) /*!< Master DMA Enable Bit */
/*
* @brief I2C Master Time Register Field definition
*/
#define I2C_MSTTIME_MSTSCLLOW (0x07 << 0) /*!< Master SCL Low Time field */
#define I2C_MSTTIME_MSTSCLHIGH (0x07 << 4) /*!< Master SCL High Time field */
/*
* @brief I2C Master Data Mask
*/
#define I2C_MSTDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Master data mask */
/*
* @brief I2C Slave Control register Bit definition
*/
#define I2C_SLVCTL_SLVCONTINUE (1 << 0) /*!< Slave Continue Bit */
#define I2C_SLVCTL_SLVNACK (1 << 1) /*!< Slave NACK Bit */
#define I2C_SLVCTL_SLVDMA (1 << 3) /*!< Slave DMA Enable Bit */
/*
* @brief I2C Slave Data Mask
*/
#define I2C_SLVDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Slave data mask */
/*
* @brief I2C Slave Address register Bit definition
*/
#define I2C_SLVADR_SADISABLE (1 << 0) /*!< Slave Address n Disable Bit */
#define I2C_SLVADR_SLVADR (0x7F << 1) /*!< Slave Address field */
#define I2C_SLVADR_MASK ((uint32_t) 0x00FF) /*!< Slave Address Mask */
/*
* @brief I2C Slave Address Qualifier 0 Register Bit definition
*/
#define I2C_SLVQUAL_QUALMODE0 (1 << 0) /*!< Slave Qualifier Mode Enable Bit */
#define I2C_SLVQUAL_SLVQUAL0 (0x7F << 1) /*!< Slave Qualifier Address for Address 0 */
/*
* @brief I2C Monitor Data Register Bit definition
*/
#define I2C_MONRXDAT_DATA (0xFF << 0) /*!< Monitor Function Receive Data Field */
#define I2C_MONRXDAT_MONSTART (1 << 8) /*!< Monitor Received Start Bit */
#define I2C_MONRXDAT_MONRESTART (1 << 9) /*!< Monitor Received Repeated Start Bit */
#define I2C_MONRXDAT_MONNACK (1 << 10) /*!< Monitor Received Nack Bit */
/**
* @brief Initialize I2C Interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function enables the I2C clock for both the master and
* slave interfaces of the given I2C peripheral. LPC_I2C1, LPC_I2C2 and
* LPC_I2C3 are available only on LPC82X devices.
*/
void Chip_I2C_Init(LPC_I2C_T *pI2C);
/**
* @brief Shutdown I2C Interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function disables the I2C clock for both the master and
* slave interfaces of the given I2C peripheral. Only LPC_I2C0 is available
* on LPC81X devices.
*/
void Chip_I2C_DeInit(LPC_I2C_T *pI2C);
/**
* @brief Sets I2C Clock Divider registers
* @param pI2C : Pointer to selected I2C peripheral
* @param clkdiv : Clock Divider value for I2C, value is between (1 - 65536)
* @return Nothing
* @note The clock to I2C block is determined by the following formula (I2C_PCLK
* is the frequency of the system clock): <br>
* I2C Clock Frequency = (I2C_PCLK)/clkdiv;
*/
static INLINE void Chip_I2C_SetClockDiv(LPC_I2C_T *pI2C, uint32_t clkdiv)
{
if ((clkdiv >= 1) && (clkdiv <= 65536)) {
pI2C->CLKDIV = clkdiv - 1;
}
else {
pI2C->CLKDIV = 0;
}
}
/**
* @brief Get I2C Clock Divider registers
* @param pI2C : Pointer to selected I2C peripheral
* @return Clock Divider value
* @note Return the divider value for the I2C block
* It is the CLKDIV register value + 1
*/
static INLINE uint32_t Chip_I2C_GetClockDiv(LPC_I2C_T *pI2C)
{
return (pI2C->CLKDIV & 0xFFFF) + 1;
}
/**
* @brief Enable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intEn : ORed Value of I2C_INTENSET_* values to enable
* @return Nothing
*/
static INLINE void Chip_I2C_EnableInt(LPC_I2C_T *pI2C, uint32_t intEn)
{
pI2C->INTENSET = intEn;
}
/**
* @brief Disable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intClr : ORed Value of I2C_INTENSET_* values to disable
* @return Nothing
*/
static INLINE void Chip_I2C_DisableInt(LPC_I2C_T *pI2C, uint32_t intClr)
{
pI2C->INTENCLR = intClr;
}
/**
* @brief Disable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intClr : ORed Value of I2C_INTENSET_* values to disable
* @return Nothing
* @note It is recommended to use the Chip_I2C_DisableInt() function
* instead of this function.
*/
static INLINE void Chip_I2C_ClearInt(LPC_I2C_T *pI2C, uint32_t intClr)
{
Chip_I2C_DisableInt(pI2C, intClr);
}
/**
* @brief Returns pending I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @return All pending interrupts, mask with I2C_INTENSET_* to determine specific interrupts
*/
static INLINE uint32_t Chip_I2C_GetPendingInt(LPC_I2C_T *pI2C)
{
return pI2C->INTSTAT & ~I2C_INTSTAT_RESERVED;
}
/**
* @}
*/
/** @defgroup I2CM_8XX CHIP: LPC8XX I2C master-only driver
* @ingroup I2C_8XX
* This driver only works in master mode. To describe the I2C transactions
* following symbols are used in driver documentation.
*
* Key to symbols
* ==============
* S (1 bit) : Start bit
* P (1 bit) : Stop bit
* Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
* A, NA (1 bit) : Acknowledge and Not-Acknowledge bit.
* Addr (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
* get a 10 bit I2C address.
* Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
* for 16 bit data.
* [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
* @{
*/
/** I2CM_8XX_STATUS_TYPES I2C master transfer status types
* @{
*/
#define I2CM_STATUS_OK 0x00 /*!< Requested Request was executed successfully. */
#define I2CM_STATUS_ERROR 0x01 /*!< Unknown error condition. */
#define I2CM_STATUS_NAK_ADR 0x02 /*!< No acknowledgement received from slave during address phase. */
#define I2CM_STATUS_BUS_ERROR 0x03 /*!< I2C bus error */
#define I2CM_STATUS_NAK_DAT 0x04 /*!< No acknowledgement received from slave during address phase. */
#define I2CM_STATUS_ARBLOST 0x05 /*!< Arbitration lost. */
#define I2CM_STATUS_BUSY 0xFF /*!< I2C transmistter is busy. */
/**
* @}
*/
/**
* @brief Master transfer data structure definitions
*/
typedef struct {
const uint8_t *txBuff; /*!< Pointer to array of bytes to be transmitted */
uint8_t *rxBuff; /*!< Pointer memory where bytes received from I2C be stored */
uint16_t txSz; /*!< Number of bytes in transmit array,
if 0 only receive transfer will be carried on */
uint16_t rxSz; /*!< Number of bytes to received,
if 0 only transmission we be carried on */
uint16_t status; /*!< Status of the current I2C transfer */
uint8_t slaveAddr; /*!< 7-bit I2C Slave address */
} I2CM_XFER_T;
/**
* @brief Set up bus speed for LPC_I2C controller
* @param pI2C : Pointer to selected I2C peripheral
* @param busSpeed : I2C bus clock rate
* @return Nothing
* @note Per I2C specification the busSpeed should be
* @li 100000 for Standard mode
* @li 400000 for Fast mode
* @li 1000000 for Fast mode plus
* IOCON registers corresponding to I2C pads should be updated
* according to the bus mode.
*/
void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed);
/**
* @brief Enable I2C Master interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note
*/
static INLINE void Chip_I2CM_Enable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_MSTEN;
}
/**
* @brief Disable I2C Master interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note
*/
static INLINE void Chip_I2CM_Disable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_MSTEN;
}
/**
* @brief Get I2C Status
* @param pI2C : Pointer to selected I2C peripheral
* @return I2C Status register value
* @note This function returns the value of the status register.
*/
static INLINE uint32_t Chip_I2CM_GetStatus(LPC_I2C_T *pI2C)
{
return pI2C->STAT & ~I2C_STAT_RESERVED;
}
/**
* @brief Clear I2C status bits (master)
* @param pI2C : Pointer to selected I2C peripheral
* @param clrStatus : Status bit to clear, ORed Value of I2C_STAT_MSTRARBLOSS and I2C_STAT_MSTSTSTPERR
* @return Nothing
* @note This function clears selected status flags.
*/
static INLINE void Chip_I2CM_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus)
{
/* Clear Master Arbitration Loss and Start, Stop Error */
pI2C->STAT = clrStatus & (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR);
}
/**
* @brief Check if I2C Master is pending
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the Master is pending else returns FALSE
* @note
*/
static INLINE bool Chip_I2CM_IsMasterPending(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_MSTPENDING) != 0;
}
/**
* @brief Get current state of the I2C Master
* @param pI2C : Pointer to selected I2C peripheral
* @return Master State Code, a value in the range of 0 - 4
* @note After the Master is pending this state code tells the reason
* for Master pending.
*/
static INLINE uint32_t Chip_I2CM_GetMasterState(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_MSTSTATE) >> 1;
}
/**
* @brief Transmit START or Repeat-START signal on I2C bus
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the controller to transmit START condition when
* the bus becomes free. This should be called only when master is pending.
* The function writes a complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_SendStart(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTSTART;
}
/**
* @brief Transmit STOP signal on I2C bus
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the controller to transmit STOP condition.
* This should be called only when master is pending. The function writes a
* complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_SendStop(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTSTOP;
}
/**
* @brief Master Continue transfer operation
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the master controller to continue transmission.
* This should be called only when master is pending. The function writes a
* complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_MasterContinue(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTCONTINUE;
}
/**
* @brief Transmit a single data byte through the I2C peripheral (master)
* @param pI2C : Pointer to selected I2C peripheral
* @param data : Byte to transmit
* @return Nothing
* @note This function attempts to place a byte into the I2C Master
* Data Register
*
*/
static INLINE void Chip_I2CM_WriteByte(LPC_I2C_T *pI2C, uint8_t data)
{
pI2C->MSTDAT = (uint32_t) data;
}
/**
* @brief Read a single byte data from the I2C peripheral (master)
* @param pI2C : Pointer to selected I2C peripheral
* @return A single byte of data read
* @note This function reads a byte from the I2C receive hold register
* regardless of I2C state.
*/
static INLINE uint8_t Chip_I2CM_ReadByte(LPC_I2C_T *pI2C)
{
return (uint8_t) (pI2C->MSTDAT & I2C_MSTDAT_DATAMASK);
}
/**
* @brief Transfer state change handler
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Returns non-zero value on completion of transfer. The @a status
* member of @a xfer structure contains the current status of the
* transfer at the end of the call.
* @note
* The parameter @a xfer should be same as the one passed to Chip_I2CM_Xfer()
* routine. This function should be called from the I2C interrupt handler
* only when a master interrupt occurs.
*/
uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @brief Transmit and Receive data in master mode
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Nothing
* @note
* The parameter @a xfer should have its member @a slaveAddr initialized
* to the 7-Bit slave address to which the master will do the xfer, Bit0
* to bit6 should have the address and Bit8 is ignored. During the transfer
* no code (like event handler) must change the content of the memory
* pointed to by @a xfer. The member of @a xfer, @a txBuff and @a txSz be
* initialized to the memory from which the I2C must pick the data to be
* transfered to slave and the number of bytes to send respectively, similarly
* @a rxBuff and @a rxSz must have pointer to memory where data received
* from slave be stored and the number of data to get from slave respectilvely.
* Following types of transfers are possible:
* - Write-only transfer: When @a rxSz member of @a xfer is set to 0.
*
* S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A] P
*
* - If I2CM_XFER_OPTION_IGNORE_NACK is set in @a options memeber
*
* S Addr Wr [A] txBuff0 [A or NA] ... txBuffN [A or NA] P
*
* - Read-only transfer: When @a txSz member of @a xfer is set to 0.
*
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
*
* - If I2CM_XFER_OPTION_LAST_RX_ACK is set in @a options memeber
*
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] A P
*
* - Read-Write transfer: When @a rxSz and @ txSz members of @a xfer are non-zero.
*
* S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A]
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
*
*/
void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @brief Transmit and Receive data in master mode
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Returns non-zero value on succesful completion of transfer.
* @note
* This function operates same as Chip_I2CM_Xfer(), but is a blocking call.
*/
uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @}
*/
/** @defgroup I2CS_8XX CHIP: LPC8XX I2C slave-only driver
* @ingroup I2C_8XX
* This driver only works in slave mode.
* @{
*/
/** @brief I2C slave service start callback
* This callback is called from the I2C slave handler when an I2C slave address is
* received and needs servicing. It's used to indicate the start of a slave transfer
* that will happen on the slave bus.
*/
typedef void (*I2CSlaveXferStart)(uint8_t addr);
/** @brief I2C slave send data callback
* This callback is called from the I2C slave handler when an I2C slave address needs
* data to send. Return 0 to NACK the master and terminate the transfer, or return
* a non-0 value with the value to send in *data.
*/
typedef uint8_t (*I2CSlaveXferSend)(uint8_t *data);
/** @brief I2C slave receive data callback
* This callback is called from the I2C slave handler when an I2C slave address has
* receive data. Return 0 to NACK the master and terminate the transfer, or return
* a non-0 value to continue the transfer.
*/
typedef uint8_t (*I2CSlaveXferRecv)(uint8_t data);
/** @brief I2C slave service done callback
* This callback is called from the I2C slave handler when an I2C slave transfer is
* completed. It's used to indicate the end of a slave transfer.
*/
typedef void (*I2CSlaveXferDone)(void);
/**
* Slave transfer are performed using 3 callbacks. These 3 callbacks handle most I2C
* slave transfer cases. When the slave is setup and a slave interrupt is receive
* and processed with the Chip_I2CS_XferHandler() function in the I2C interrupt handler,
* one of these 3 callbacks is called. The callbacks can be used for unsized transfers
* from the master.
*
* When an address is received, the SlaveXferAddr() callback is called with the
* received address. Only addresses enabled in the slave controller will be handled.
* The slave controller can support up to 4 slave addresses.
*
* If the master is going to perform a read operation, the SlaveXferSend() callback
* is called. Place the data byte to send in *data and return a non-0 value to the
* caller, or return 0 to NACK the master. (Note the master ACKS/NACKS to slave
* on reads, so this won't necessarily stop the slave transfer.)<br>
*
* If the master performs a write operation, the SlaveXferRecv() callback is called
* with the received data. Return a non-0 value to the caller, or return 0 to NACK
* the master.<br>
*
* Once the transfer completes, the SlaveXferDone() callback will be called.<br>
*/
typedef struct {
I2CSlaveXferStart slaveStart; /*!< Called when an matching I2C slave address is received */
I2CSlaveXferSend slaveSend; /*!< Called when a byte is needed to send to master */
I2CSlaveXferRecv slaveRecv; /*!< Called when a byte is received from master */
I2CSlaveXferDone slaveDone; /*!< Called when a slave transfer is complete */
} I2CS_XFER_T;
/**
* @brief Enable I2C slave interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note Do not call this function until the slave interface is fully configured.
*/
STATIC INLINE void Chip_I2CS_Enable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_SLVEN;
}
/**
* @brief Disable I2C slave interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_Disable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_SLVEN;
}
/**
* @brief Get I2C Status
* @param pI2C : Pointer to selected I2C peripheral
* @return I2C Status register value
* @note This function returns the value of the status register.
*/
STATIC INLINE uint32_t Chip_I2CS_GetStatus(LPC_I2C_T *pI2C)
{
return pI2C->STAT & ~I2C_STAT_RESERVED;
}
/**
* @brief Clear I2C status bits (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @param clrStatus : Status bit to clear, must be I2C_STAT_SLVDESEL
* @return Nothing
* @note This function clears selected status flags.
*/
STATIC INLINE void Chip_I2CS_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus)
{
pI2C->STAT = clrStatus & I2C_STAT_SLVDESEL;
}
/**
* @brief Check if I2C slave is pending
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is pending else returns FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlavePending(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVPENDING) != 0;
}
/**
* @brief Check if I2C slave is selected
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is is selected, otherwise FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlaveSelected(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVSEL) != 0;
}
/**
* @brief Check if I2C slave is deselected
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is is deselected, otherwise FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlaveDeSelected(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVDESEL) != 0;
}
/**
* @brief Get current state of the I2C slave
* @param pI2C : Pointer to selected I2C peripheral
* @return slave State Code, a value of type I2C_STAT_SLVCODE_*
* @note After the slave is pending this state code tells the reason
* for slave pending.
*/
STATIC INLINE uint32_t Chip_I2CS_GetSlaveState(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVSTATE) >> 9;
}
/**
* @brief Returns the current slave address match index
* @param pI2C : Pointer to selected I2C peripheral
* @return slave match index, 0 - 3
*/
STATIC INLINE uint32_t Chip_I2CS_GetSlaveMatchIndex(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVIDX) >> 12;
}
/**
* @brief Slave Continue transfer operation (ACK)
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the slave controller to continue transmission.
* This should be called only when slave is pending. The function writes a
* complete value to slave Control register, ORing is not advised.
*/
STATIC INLINE void Chip_I2CS_SlaveContinue(LPC_I2C_T *pI2C)
{
pI2C->SLVCTL = I2C_SLVCTL_SLVCONTINUE;
}
/**
* @brief Slave NACK operation
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the slave controller to NAK the master.
*/
STATIC INLINE void Chip_I2CS_SlaveNACK(LPC_I2C_T *pI2C)
{
pI2C->SLVCTL = I2C_SLVCTL_SLVNACK;
}
/**
* @brief Transmit a single data byte through the I2C peripheral (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @param data : Byte to transmit
* @return Nothing
* @note This function attempts to place a byte into the I2C slave
* Data Register
*
*/
STATIC INLINE void Chip_I2CS_WriteByte(LPC_I2C_T *pI2C, uint8_t data)
{
pI2C->SLVDAT = (uint32_t) data;
}
/**
* @brief Read a single byte data from the I2C peripheral (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @return A single byte of data read
* @note This function reads a byte from the I2C receive hold register
* regardless of I2C state.
*/
STATIC INLINE uint8_t Chip_I2CS_ReadByte(LPC_I2C_T *pI2C)
{
return (uint8_t) (pI2C->SLVDAT & I2C_SLVDAT_DATAMASK);
}
/**
* @brief Set a I2C slave address for slave operation
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @param slvAddr : Slave Address for the index (7-bits, bit 7 = 0)
* @return Nothing
* @note Setting a slave address also enables the slave address. Do
* not 'pre-shift' the slave address.
*/
STATIC INLINE void Chip_I2CS_SetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum, uint8_t slvAddr)
{
pI2C->SLVADR[slvNum] = (uint32_t) (slvAddr << 1);
}
/**
* @brief Return a I2C programmed slave address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE uint8_t Chip_I2CS_GetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
return (pI2C->SLVADR[slvNum] >> 1) & 0x7F;
}
/**
* @brief Enable a I2C address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_EnableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) & ~I2C_SLVADR_SADISABLE;
}
/**
* @brief Disable a I2C address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_DisableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) | I2C_SLVADR_SADISABLE;
}
/**
* @brief Setup slave qialifier address
* @param pI2C : Pointer to selected I2C peripheral
* @param extend : true to extend I2C slave detect address 0 range, or false to match to corresponding bits
* @param slvNum : Slave address qualifier, see SLVQUAL0 register in User Manual
* @return Nothing
* @note Do not 'pre-shift' the slave address.
*/
STATIC INLINE void Chip_I2CS_SetSlaveQual0(LPC_I2C_T *pI2C, bool extend, uint8_t slvNum)
{
slvNum = slvNum << 1;
if (extend) {
slvNum |= I2C_SLVQUAL_QUALMODE0;
}
pI2C->SLVQUAL0 = slvNum;
}
/**
* @brief Slave transfer state change handler
* @param pI2C : Pointer to selected I2C peripheral
* @param xfers : Pointer to a I2CS_MULTI_XFER_T structure see notes below
* @return Returns non-zero value on completion of transfer
* @note See @ref I2CS_XFER_T for more information on this function. When using
* this function, the I2C_INTENSET_SLVPENDING and I2C_INTENSET_SLVDESEL interrupts
* should be enabled and setup in the I2C interrupt handler to call this function
* when they fire.
*/
uint32_t Chip_I2CS_XferHandler(LPC_I2C_T *pI2C, const I2CS_XFER_T *xfers);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __I2C_COMMON_8XX_H_ */

View File

@ -0,0 +1,179 @@
/*
* @brief Common FLASH support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Prepare sector for write operation */
uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector)
{
uint32_t command[5], result[5];
command[0] = IAP_PREWRRITE_CMD;
command[1] = strSector;
command[2] = endSector;
iap_entry(command, result);
return result[0];
}
/* Copy RAM to flash */
uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt)
{
uint32_t command[5], result[5];
command[0] = IAP_WRISECTOR_CMD;
command[1] = dstAdd;
command[2] = (uint32_t) srcAdd;
command[3] = byteswrt;
command[4] = SystemCoreClock / 1000;
iap_entry(command, result);
return result[0];
}
/* Erase sector */
uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector)
{
uint32_t command[5], result[5];
command[0] = IAP_ERSSECTOR_CMD;
command[1] = strSector;
command[2] = endSector;
command[3] = SystemCoreClock / 1000;
iap_entry(command, result);
return result[0];
}
/* Blank check sector */
uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector)
{
uint32_t command[5], result[5];
command[0] = IAP_BLANK_CHECK_SECTOR_CMD;
command[1] = strSector;
command[2] = endSector;
iap_entry(command, result);
return result[0];
}
/* Read part identification number */
uint32_t Chip_IAP_ReadPID(void)
{
uint32_t command[5], result[5];
command[0] = IAP_REPID_CMD;
iap_entry(command, result);
return result[1];
}
/* Read boot code version number */
uint32_t Chip_IAP_ReadBootCode(void)
{
uint32_t command[5], result[5];
command[0] = IAP_READ_BOOT_CODE_CMD;
iap_entry(command, result);
return result[1] & 0xffff;
}
/* IAP compare */
uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp)
{
uint32_t command[5], result[5];
command[0] = IAP_COMPARE_CMD;
command[1] = dstAdd;
command[2] = srcAdd;
command[3] = bytescmp;
iap_entry(command, result);
return result[0];
}
/* Reinvoke ISP */
uint8_t Chip_IAP_ReinvokeISP(void)
{
uint32_t command[5], result[5];
command[0] = IAP_REINVOKE_ISP_CMD;
iap_entry(command, result);
return result[0];
}
/* Read the unique ID */
uint32_t Chip_IAP_ReadUID(uint32_t* uid)
{
uint32_t command[5], result[5];
uint32_t i;
command[0] = IAP_READ_UID_CMD;
iap_entry(command, result);
for (i=0; i<4; i++)
*(uid+i) = result[i+1];
return result[0];
}
/* Erase page */
uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage)
{
uint32_t command[5], result[5];
command[0] = IAP_ERASE_PAGE_CMD;
command[1] = strPage;
command[2] = endPage;
command[3] = SystemCoreClock / 1000;
iap_entry(command, result);
return result[0];
}

View File

@ -0,0 +1,184 @@
/*
* @brief Common IAP support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __IAP_H_
#define __IAP_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup COMMON_IAP CHIP: Common Chip ISP/IAP commands and return codes
* @ingroup CHIP_Common
* @{
*/
/* IAP command definitions */
#define IAP_PREWRRITE_CMD 50 /*!< Prepare sector for write operation command */
#define IAP_WRISECTOR_CMD 51 /*!< Write Sector command */
#define IAP_ERSSECTOR_CMD 52 /*!< Erase Sector command */
#define IAP_BLANK_CHECK_SECTOR_CMD 53 /*!< Blank check sector */
#define IAP_REPID_CMD 54 /*!< Read PartID command */
#define IAP_READ_BOOT_CODE_CMD 55 /*!< Read Boot code version */
#define IAP_COMPARE_CMD 56 /*!< Compare two RAM address locations */
#define IAP_REINVOKE_ISP_CMD 57 /*!< Reinvoke ISP */
#define IAP_READ_UID_CMD 58 /*!< Read UID */
#define IAP_ERASE_PAGE_CMD 59 /*!< Erase page */
#define IAP_EEPROM_WRITE 61 /*!< EEPROM Write command */
#define IAP_EEPROM_READ 62 /*!< EEPROM READ command */
/* IAP response definitions */
#define IAP_CMD_SUCCESS 0 /*!< Command is executed successfully */
#define IAP_INVALID_COMMAND 1 /*!< Invalid command */
#define IAP_SRC_ADDR_ERROR 2 /*!< Source address is not on word boundary */
#define IAP_DST_ADDR_ERROR 3 /*!< Destination address is not on a correct boundary */
#define IAP_SRC_ADDR_NOT_MAPPED 4 /*!< Source address is not mapped in the memory map */
#define IAP_DST_ADDR_NOT_MAPPED 5 /*!< Destination address is not mapped in the memory map */
#define IAP_COUNT_ERROR 6 /*!< Byte count is not multiple of 4 or is not a permitted value */
#define IAP_INVALID_SECTOR 7 /*!< Sector number is invalid or end sector number is greater than start sector number */
#define IAP_SECTOR_NOT_BLANK 8 /*!< Sector is not blank */
#define IAP_SECTOR_NOT_PREPARED 9 /*!< Command to prepare sector for write operation was not executed */
#define IAP_COMPARE_ERROR 10 /*!< Source and destination data not equal */
#define IAP_BUSY 11 /*!< Flash programming hardware interface is busy */
#define IAP_PARAM_ERROR 12 /*!< nsufficient number of parameters or invalid parameter */
#define IAP_ADDR_ERROR 13 /*!< Address is not on word boundary */
#define IAP_ADDR_NOT_MAPPED 14 /*!< Address is not mapped in the memory map */
#define IAP_CMD_LOCKED 15 /*!< Command is locked */
#define IAP_INVALID_CODE 16 /*!< Unlock code is invalid */
#define IAP_INVALID_BAUD_RATE 17 /*!< Invalid baud rate setting */
#define IAP_INVALID_STOP_BIT 18 /*!< Invalid stop bit setting */
#define IAP_CRP_ENABLED 19 /*!< Code read protection enabled */
/* IAP_ENTRY API function type */
typedef void (*IAP_ENTRY_T)(unsigned int[], unsigned int[]);
/**
* @brief Prepare sector for write operation
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Status code to indicate the command is executed successfully or not
* @note This command must be executed before executing "Copy RAM to flash"
* or "Erase Sector" command.
* The end sector must be greater than or equal to start sector number
*/
uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector);
/**
* @brief Copy RAM to flash
* @param dstAdd : Destination FLASH address where data bytes are to be written
* @param srcAdd : Source RAM address where data bytes are to be read
* @param byteswrt : Number of bytes to be written
* @return Status code to indicate the command is executed successfully or not
* @note The addresses should be a 256 byte boundary and the number of bytes
* should be 256 | 512 | 1024 | 4096
*/
uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt);
/**
* @brief Erase sector
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Status code to indicate the command is executed successfully or not
* @note The end sector must be greater than or equal to start sector number
*/
uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector);
/**
* @brief Blank check a sector or multiples sector of on-chip flash memory
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK
* @note The end sector must be greater than or equal to start sector number
*/
// FIXME - There are two return value (result[0] & result[1]
// Result0:Offset of the first non blank word location if the Status Code is
// SECTOR_NOT_BLANK.
// Result1:Contents of non blank word location.
uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector);
/**
* @brief Read part identification number
* @return Part identification number
*/
uint32_t Chip_IAP_ReadPID(void);
/**
* @brief Read boot code version number
* @return Boot code version number
*/
uint32_t Chip_IAP_ReadBootCode(void);
/**
* @brief Compare the memory contents at two locations
* @param dstAdd : Destination of the RAM address of data bytes to be compared
* @param srcAdd : Source of the RAM address of data bytes to be compared
* @param bytescmp : Number of bytes to be compared
* @return Offset of the first mismatch of the status code is COMPARE_ERROR
* @note The addresses should be a word boundary and number of bytes should be
* a multiply of 4
*/
uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp);
/**
* @brief IAP reinvoke ISP to invoke the bootloader in ISP mode
* @return none
*/
uint8_t Chip_IAP_ReinvokeISP(void);
/**
* @brief Read the unique ID
* @return Status code to indicate the command is executed successfully or not
*/
uint32_t Chip_IAP_ReadUID(uint32_t* uid);
/**
* @brief Erase a page or multiple papers of on-chip flash memory
* @param strPage : Start page number
* @param endPage : End page number
* @return Status code to indicate the command is executed successfully or not
* @note The page number must be greater than or equal to start page number
*/
// FIXME - There are four return value
// Result0:The first 32-bit word (at the lowest address)
// Result1:The second 32-bit word.
// Result2:The third 32-bit word.
// Result3:The fourth 32-bit word.
uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __IAP_H_ */

View File

@ -0,0 +1,156 @@
/*
* @brief LPC8xx INPUT MUX chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __INMUX_8XX_H_
#define __INMUX_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup INMUX_8XX CHIP: LPC8xx INPUT Mux Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
typedef struct {
__IO uint32_t DMA_INMUX_INMUX[2]; /*!< DMA Trigger Input 20 & 21 PINMUX 0-1 */
__O uint32_t RESERVED[6]; /*!< Reserved; Should not be used */
__IO uint32_t SCT0_INMUX[4]; /*!< Input mux register for SCT0; INPUT0-3 */
} LPC_INMUX_T;
/**
* @brief DMA INPUT MUX Index see Chip_INMUX_SetDMAOTrig()
*/
typedef enum {
DMA_INMUX_0, /*!< MUX for DMA input trigger 20 */
DMA_INMUX_1, /*!< MUX for DMA input trigger 21 */
}DMA_INMUX_T;
/**
* @brief SCT Input Mux Index; See Chip_INMUX_SetSCTInMux()
*/
typedef enum {
SCT_INMUX_0, /*!< Input mux for SCT0; INPUT 0 */
SCT_INMUX_1, /*!< Input mux for SCT0; INPUT 1 */
SCT_INMUX_2, /*!< Input mux for SCT0; INPUT 2 */
SCT_INMUX_3, /*!< Input mux for SCT0; INPUT 3 */
} SCT_INMUX_T;
/**
* @brief SCT INPUT triggers
*/
typedef enum {
SCT_INP_IN0, /*!< SCT0_IN0 selected by Pin Matrix */ /* FIXME: UM hints about changes */
SCT_INP_IN1, /*!< SCT0_IN1 selected by Pin Matrix */
SCT_INP_IN2, /*!< SCT0_IN2 selected by Pin Matrix */
SCT_INP_IN3, /*!< SCT0_IN3 selected by Pin Matrix */
SCT_INP_ADC_THCMP_IRQ, /*!< ADC Threshold compare IRQ */
SCT_INP_ACMP_O, /*!< Analog comparator output */
SCT_INP_ARM_TXEV, /*!< ARM TX Event */
SCT_INP_DEBUG_HALTED, /*!< Debug halted event */
} SCT_INP_T;
/**
* @brief Select a trigger source for a DMA channel
* @param pINMUX : The base of INPUT MUX register block
* @param imux : Index of DMA input mux
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_INMUX_SetDMAOTrig(LPC_INMUX_T *pINMUX, DMA_INMUX_T imux, DMA_CHID_T ch)
{
pINMUX->DMA_INMUX_INMUX[imux] = ch;
}
/**
* @brief Select a trigger source SCT module
* @param pINMUX : The base of INPUT MUX register block
* @param isct : Index of SCT input mux
* @param trig : SCT Input function that will cause the trigger
* @return Nothing
*/
STATIC INLINE void Chip_INMUX_SetSCTInMux(LPC_INMUX_T *pINMUX, SCT_INMUX_T isct, SCT_INP_T trig)
{
pINMUX->SCT0_INMUX[isct] = trig;
}
/** @defgroup DMATRIGMUX_8XX CHIP: LPC8xx DMA trigger selection driver
* @{
*/
/**
* @brief DMA trigger pin muxing structure
*/
typedef struct { /*!< DMA trigger pin muxing register structure */
__IO uint32_t DMA_ITRIG_INMUX[MAX_DMA_CHANNEL]; /*!< Trigger input select register for DMA channels */
} LPC_DMATRIGMUX_T;
/* DMA triggers that can mapped to DMA channels */
typedef enum {
DMATRIG_ADC_SEQA_IRQ = 0, /*!< ADC0 sequencer A interrupt as trigger */
DMATRIG_ADC_SEQB_IRQ, /*!< ADC0 sequencer B interrupt as trigger */
DMATRIG_SCT0_DMA0, /*!< SCT 0, DMA 0 as trigger */
DMATRIG_SCT0_DMA1, /*!< SCT 1, DMA 1 as trigger */
DMATRIG_ACMP_O, /*!< Analog comparator output */
DMATRIG_PINT0, /*!< Pin interrupt 0 as trigger */
DMATRIG_PINT1, /*!< Pin interrupt 1 as trigger */
DMATRIG_DMA_INMUX0, /*!< DMA Trigger MUX0 */
DMATRIG_DMA_INMUX1, /*!< DMA Trigger MUX1 */
} DMA_TRIGSRC_T;
/**
* @brief Select a trigger source for a DMA channel
* @param pDMATRIG : The base of DMA trigger setup block on the chip
* @param ch : DMA channel ID
* @param trig : Trigger source for the DMA channel
* @return Nothing
* @note A DMA trigger source only needs to be setup when the DMA is setup
* for hardware trigger mode (when Chip_DMA_SetupChannelConfig() is
* called with DMA_CFG_HWTRIGEN as OR'ed option).
*/
STATIC INLINE void Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX_T *pDMATRIG, DMA_CHID_T ch, DMA_TRIGSRC_T trig)
{
pDMATRIG->DMA_ITRIG_INMUX[ch] = (uint32_t) trig;
}
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __INMUX_8XX_H_ */

View File

@ -0,0 +1,343 @@
/*
* @brief LPC8xx Multi-Rate Timer (MRT) registers and driver functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __MRT_8XX_H_
#define __MRT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup MRT_8XX CHIP: LPC8xx Multi-Rate Timer driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx MRT chip configuration
*/
#define MRT_CHANNELS_NUM (4)
#define MRT_NO_IDLE_CHANNEL (0x40)
/**
* @brief MRT register block structure
*/
typedef struct {
__IO uint32_t INTVAL; /*!< Timer interval register */
__O uint32_t TIMER; /*!< Timer register */
__IO uint32_t CTRL; /*!< Timer control register */
__IO uint32_t STAT; /*!< Timer status register */
} LPC_MRT_CH_T;
/**
* @brief MRT register block structure
*/
typedef struct {
LPC_MRT_CH_T CHANNEL[MRT_CHANNELS_NUM];
uint32_t unused[45];
__O uint32_t IDLE_CH;
__IO uint32_t IRQ_FLAG;
} LPC_MRT_T;
/* Reserved bits masks for registers */
#define MRT_CTRL_RESERVED (~7)
#define MRT_STAT_RESERVED (~3)
/**
* @brief MRT Interrupt Modes enum
*/
typedef enum MRT_MODE {
MRT_MODE_REPEAT = (0 << 1), /*!< MRT Repeat interrupt mode */
MRT_MODE_ONESHOT = (1 << 1) /*!< MRT One-shot interrupt mode */
} MRT_MODE_T;
/**
* @brief MRT register bit fields & masks
*/
/* MRT Time interval register bit fields */
#define MRT_INTVAL_IVALUE (0x7FFFFFFFUL) /* Maximum interval load value and mask */
#define MRT_INTVAL_LOAD (0x80000000UL) /* Force immediate load of timer interval register bit */
/* MRT Control register bit fields & masks */
#define MRT_CTRL_INTEN_MASK (0x01)
#define MRT_CTRL_MODE_MASK (0x06)
/* MRT Status register bit fields & masks */
#define MRT_STAT_INTFLAG (0x01)
#define MRT_STAT_RUNNING (0x02)
/* Pointer to individual MR register blocks */
#define LPC_MRT_CH0 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[0])
#define LPC_MRT_CH1 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[1])
#define LPC_MRT_CH2 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[2])
#define LPC_MRT_CH3 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[3])
#define LPC_MRT_CH(ch) ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[(ch)])
/* Global interrupt flag register interrupt mask/clear values */
#define MRT0_INTFLAG (1)
#define MRT1_INTFLAG (2)
#define MRT2_INTFLAG (4)
#define MRT3_INTFLAG (8)
#define MRTn_INTFLAG(ch) (1 << (ch))
/**
* @brief Initializes the MRT
* @return Nothing
*/
STATIC INLINE void Chip_MRT_Init(void)
{
/* Enable the clock to the register interface */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT);
/* Reset MRT */
Chip_SYSCTL_PeriphReset(RESET_MRT);
}
/**
* @brief De-initializes the MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_DeInit(void)
{
/* Disable the clock to the MRT */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MRT);
}
/**
* @brief Returns a pointer to the register block for a MRT channel
* @param ch : MRT channel tog et register block for (0..3)
* @return Pointer to the MRT register block for the channel
*/
STATIC INLINE LPC_MRT_CH_T *Chip_MRT_GetRegPtr(uint8_t ch)
{
return LPC_MRT_CH(ch);
}
/**
* @brief Returns the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @return Timer time interval value (IVALUE)
*/
STATIC INLINE uint32_t Chip_MRT_GetInterval(LPC_MRT_CH_T *pMRT)
{
return pMRT->INTVAL;
}
/**
* @brief Sets the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @param interval : The interval timeout (31-bits)
* @return Nothing
* @note Setting bit 31 in timer time interval register causes the time interval value
* to load immediately, otherwise the time interval value will be loaded in
* next timer cycle.<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500); // Will load timer interval after internal expires
*/
STATIC INLINE void Chip_MRT_SetInterval(LPC_MRT_CH_T *pMRT, uint32_t interval)
{
pMRT->INTVAL = interval;
}
/**
* @brief Returns the current timer value
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer value
*/
STATIC INLINE uint32_t Chip_MRT_GetTimer(LPC_MRT_CH_T *pMRT)
{
return pMRT->TIMER;
}
/**
* @brief Returns true if the timer is enabled
* @param pMRT : Pointer to selected MRT Channel
* @return True if enabled, Flase if not enabled
*/
STATIC INLINE bool Chip_MRT_GetEnabled(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->CTRL & MRT_CTRL_INTEN_MASK) != 0);
}
/**
* @brief Enables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetEnabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL = MRT_CTRL_INTEN_MASK | (pMRT->CTRL & ~MRT_CTRL_RESERVED);
}
/**
* @brief Disables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetDisabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL &= ~(MRT_CTRL_INTEN_MASK | MRT_CTRL_RESERVED);
}
/**
* @brief Returns the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer mode
*/
STATIC INLINE MRT_MODE_T Chip_MRT_GetMode(LPC_MRT_CH_T *pMRT)
{
return (MRT_MODE_T) (pMRT->CTRL & MRT_CTRL_MODE_MASK);
}
/**
* @brief Sets the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @param mode : Timer mode
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetMode(LPC_MRT_CH_T *pMRT, MRT_MODE_T mode)
{
uint32_t reg;
reg = pMRT->CTRL & ~(MRT_CTRL_MODE_MASK | MRT_CTRL_RESERVED);
pMRT->CTRL = reg | (uint32_t) mode;
}
/**
* @brief Check if the timer is configured in repeat mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in repeat mode, False if in one-shot mode
*/
STATIC INLINE bool Chip_MRT_IsRepeatMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? false : true;
}
/**
* @brief Check if the timer is configured in one-shot mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in one-shot mode, False if in repeat mode
*/
STATIC INLINE bool Chip_MRT_IsOneShotMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? true : false;
}
/**
* @brief Check if the timer has an interrupt pending
* @param pMRT : Pointer to selected MRT Channel
* @return True if interrupt is pending, False if no interrupt is pending
*/
STATIC INLINE bool Chip_MRT_IntPending(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_INTFLAG) != 0);
}
/**
* @brief Clears the pending interrupt (if any)
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_IntClear(LPC_MRT_CH_T *pMRT)
{
pMRT->STAT = MRT_STAT_INTFLAG | (pMRT->STAT & ~MRT_STAT_RESERVED);
}
/**
* @brief Check if the timer is running
* @param pMRT : Pointer to selected MRT Channel
* @return True if running, False if stopped
*/
STATIC INLINE bool Chip_MRT_Running(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_RUNNING) != 0);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (unshifted in bits 7..4)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannel(void)
{
return (uint8_t) (LPC_MRT->IDLE_CH);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (shifted in bits 3..0)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannelShifted(void)
{
return (uint8_t) (Chip_MRT_GetIdleChannel() >> 4);
}
/**
* @brief Returns the interrupt pending status for all MRT channels
* @return IRQ pending channel bitfield(bit 0 = MRT0, bit 1 = MRT1, etc.)
*/
STATIC INLINE uint32_t Chip_MRT_GetIntPending(void)
{
return LPC_MRT->IRQ_FLAG;
}
/**
* @brief Returns the interrupt pending status for a singel MRT channel
* @param ch : Channel to check pending interrupt status for
* @return IRQ pending channel number
*/
STATIC INLINE bool Chip_MRT_GetIntPendingByChannel(uint8_t ch)
{
return (bool) (((LPC_MRT->IRQ_FLAG >> ch) & 1) != 0);
}
/**
* @brief Clears the interrupt pending status for one or more MRT channels
* @param mask : Channels to clear (bit 0 = MRT0, bit 1 = MRT1, etc.)
* @return Nothing
* @note Use this function to clear multiple interrupt pending states in
* a single call via the IRQ_FLAG register. Performs the same function for
* all MRT channels in a single call as the Chip_MRT_IntClear() does for a
* single channel.
*/
STATIC INLINE void Chip_MRT_ClearIntPending(uint32_t mask)
{
LPC_MRT->IRQ_FLAG = mask;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __MRT_8XX_H_ */

View File

@ -0,0 +1,111 @@
/*
* @brief LPC8xx specific stopwatch implementation
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#include "stopwatch.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Precompute these to optimize runtime */
static uint32_t ticksPerSecond;
static uint32_t ticksPerMs;
static uint32_t ticksPerUs;
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize stopwatch */
void StopWatch_Init(void)
{
Chip_MRT_Init();
Chip_MRT_SetMode(LPC_MRT_CH1, MRT_MODE_REPEAT);
Chip_MRT_SetInterval(LPC_MRT_CH1, 0x7ffffff | MRT_INTVAL_LOAD);
Chip_MRT_GetEnabled(LPC_MRT_CH1);
/* Pre-compute tick rate. */
ticksPerSecond = Chip_Clock_GetSystemClockRate();
ticksPerMs = ticksPerSecond / 1000;
ticksPerUs = ticksPerSecond / 1000000;
}
/* reset stopwatch */
void StopWatch_Reset(void)
{
Chip_MRT_SetInterval(LPC_MRT_CH1, 0x7ffffff | MRT_INTVAL_LOAD);
}
/* Start a stopwatch */
uint32_t StopWatch_Start(void)
{
/* Return the current timer count. */
return 0x7ffffff - Chip_MRT_GetTimer(LPC_MRT_CH1);
}
/* Returns number of ticks per second of the stopwatch timer */
uint32_t StopWatch_TicksPerSecond(void)
{
return ticksPerSecond;
}
/* Converts from stopwatch ticks to mS. */
uint32_t StopWatch_TicksToMs(uint32_t ticks)
{
return ticks / ticksPerMs;
}
/* Converts from stopwatch ticks to uS. */
uint32_t StopWatch_TicksToUs(uint32_t ticks)
{
return ticks / ticksPerUs;
}
/* Converts from mS to stopwatch ticks. */
uint32_t StopWatch_MsToTicks(uint32_t mS)
{
return mS * ticksPerMs;
}
/* Converts from uS to stopwatch ticks. */
uint32_t StopWatch_UsToTicks(uint32_t uS)
{
return uS * ticksPerUs;
}

View File

@ -0,0 +1,143 @@
/*
* @brief Common stopwatch support
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __STOPWATCH_H_
#define __STOPWATCH_H_
#include "cmsis.h"
/** @defgroup Stop_Watch CHIP: Stopwatch primitives.
* @ingroup CHIP_Common
* @{
*/
/**
* @brief Initialize stopwatch
* @return Nothing
*/
void StopWatch_Init(void);
/**
* @brief reset stopwatch
* @return Nothing
*/
void StopWatch_Reset(void);
/**
* @brief Start a stopwatch
* @return Current cycle count
*/
uint32_t StopWatch_Start(void);
/**
* @brief Returns number of ticks elapsed since stopwatch was started
* @param startTime : Time returned by StopWatch_Start().
* @return Number of ticks elapsed since stopwatch was started
*/
STATIC INLINE uint32_t StopWatch_Elapsed(uint32_t startTime)
{
return StopWatch_Start() - startTime;
}
/**
* @brief Returns number of ticks per second of the stopwatch timer
* @return Number of ticks per second of the stopwatch timer
*/
uint32_t StopWatch_TicksPerSecond(void);
/**
* @brief Converts from stopwatch ticks to mS.
* @param ticks : Duration in ticks to convert to mS.
* @return Number of mS in given number of ticks
*/
uint32_t StopWatch_TicksToMs(uint32_t ticks);
/**
* @brief Converts from stopwatch ticks to uS.
* @param ticks : Duration in ticks to convert to uS.
* @return Number of uS in given number of ticks
*/
uint32_t StopWatch_TicksToUs(uint32_t ticks);
/**
* @brief Converts from mS to stopwatch ticks.
* @param mS : Duration in mS to convert to ticks.
* @return Number of ticks in given number of mS
*/
uint32_t StopWatch_MsToTicks(uint32_t mS);
/**
* @brief Converts from uS to stopwatch ticks.
* @param uS : Duration in uS to convert to ticks.
* @return Number of ticks in given number of uS
*/
uint32_t StopWatch_UsToTicks(uint32_t uS);
/**
* @brief Delays the given number of ticks using stopwatch primitives
* @param ticks : Number of ticks to delay
* @return Nothing
*/
STATIC INLINE void StopWatch_DelayTicks(uint32_t ticks)
{
uint32_t startTime = StopWatch_Start();
while (StopWatch_Elapsed(startTime) < ticks) {}
}
/**
* @brief Delays the given number of mS using stopwatch primitives
* @param mS : Number of mS to delay
* @return Nothing
*/
STATIC INLINE void StopWatch_DelayMs(uint32_t mS)
{
uint32_t ticks = StopWatch_MsToTicks(mS);
uint32_t startTime = StopWatch_Start();
while (StopWatch_Elapsed(startTime) < ticks) {}
}
/**
* @brief Delays the given number of uS using stopwatch primitives
* @param uS : Number of uS to delay
* @return Nothing
*/
STATIC INLINE void StopWatch_DelayUs(uint32_t uS)
{
uint32_t ticks = StopWatch_UsToTicks(uS);
uint32_t startTime = StopWatch_Start();
while (StopWatch_Elapsed(startTime) < ticks) {}
}
/**
* @}
*/
#endif /* __STOPWATCH_H_ */

View File

@ -0,0 +1,39 @@
#ifndef _PERI_DRIVER_H_
#define _PERI_DRIVER_H_
#include "chip.h"
#include "rom/romapi_8xx.h"
#include "acmp/acmp_8xx.h"
#if defined(CHIP_LPC82X)
#include "adc/adc_8xx.h"
#endif
#include "crc/crc_8xx.h"
#if defined(CHIP_LPC82X)
#include "dma/dma_8xx.h"
#endif
#include "gpio/gpio_8xx.h"
#include "i2c/i2c_8xx.h"
#include "iap/iap.h"
#include "crc/crc_8xx.h"
#if defined(CHIP_LPC82X)
#include "inmux/inmux_8xx.h"
#endif
#include "mrt/mrt_8xx.h"
#include "mrt/stopwatch.h"
#include "pinint/pinint_8xx.h"
#include "pmu/pmu_8xx.h"
#include "sctimer/sct_8xx.h"
#include "sctimer/sct_pwm_8xx.h"
#include "spi/spi_8xx.h"
#include "uart/uart_8xx.h"
#include "wkt/wkt_8xx.h"
#include "wwdt/wwdt_8xx.h"
#include "iap/iap.h"
#endif

View File

@ -0,0 +1,81 @@
/*
* @brief LPC8xx Pin Interrupt and Pattern Match driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Set source for pattern match engine */
void Chip_PININT_SetPatternMatchSrc(LPC_PININT_T *pPININT, uint8_t chan, Chip_PININT_BITSLICE_T slice)
{
uint32_t pmsrc_reg;
/* Source source for pattern matching */
pmsrc_reg = pPININT->PMSRC & ~((PININT_SRC_BITSOURCE_MASK << (PININT_SRC_BITSOURCE_START + (slice * 3)))
| PININT_PMSRC_RESERVED);
pPININT->PMSRC = pmsrc_reg | (chan << (PININT_SRC_BITSOURCE_START + (slice * 3)));
}
/* Configure Pattern match engine */
void Chip_PININT_SetPatternMatchConfig(LPC_PININT_T *pPININT, Chip_PININT_BITSLICE_T slice,
Chip_PININT_BITSLICE_CFG_T slice_cfg, bool end_point)
{
uint32_t pmcfg_reg;
/* Configure bit slice configuration */
pmcfg_reg = pPININT->PMCFG & ~((PININT_SRC_BITCFG_MASK << (PININT_SRC_BITCFG_START + (slice * 3)))
| PININT_PMCFG_RESERVED);
pPININT->PMCFG = pmcfg_reg | (slice_cfg << (PININT_SRC_BITCFG_START + (slice * 3)));
/* If end point is true, enable the bits */
if (end_point == true)
{
/* By default slice 7 is final component */
if (slice != PININTBITSLICE7)
{
pPININT->PMCFG = (0x1 << slice) | (pPININT->PMCFG & ~PININT_PMCFG_RESERVED);
}
}
}

View File

@ -0,0 +1,389 @@
/*
* @brief LPC8xx Pin Interrupt and Pattern Match Registers and driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __PININT_8XX_H_
#define __PININT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup PININT_8XX CHIP: LPC8xx Pin Interrupt and Pattern Match driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx Pin Interrupt and Pattern Match register block structure
*/
typedef struct { /*!< (@ 0xA0004000) PIN_INT Structure */
__IO uint32_t ISEL; /*!< (@ 0xA0004000) Pin Interrupt Mode register */
__IO uint32_t IENR; /*!< (@ 0xA0004004) Pin Interrupt Enable (Rising) register */
__IO uint32_t SIENR; /*!< (@ 0xA0004008) Set Pin Interrupt Enable (Rising) register */
__IO uint32_t CIENR; /*!< (@ 0xA000400C) Clear Pin Interrupt Enable (Rising) register */
__IO uint32_t IENF; /*!< (@ 0xA0004010) Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t SIENF; /*!< (@ 0xA0004014) Set Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t CIENF; /*!< (@ 0xA0004018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
__IO uint32_t RISE; /*!< (@ 0xA000401C) Pin Interrupt Rising Edge register */
__IO uint32_t FALL; /*!< (@ 0xA0004020) Pin Interrupt Falling Edge register */
__IO uint32_t IST; /*!< (@ 0xA0004024) Pin Interrupt Status register */
__IO uint32_t PMCTRL; /*!< (@ 0xA0004028) GPIO pattern match interrupt control register */
__IO uint32_t PMSRC; /*!< (@ 0xA000402C) GPIO pattern match interrupt bit-slice source register */
__IO uint32_t PMCFG; /*!< (@ 0xA0004030) GPIO pattern match interrupt bit slice configuration register */
} LPC_PININT_T;
/* Reserved bits masks for registers */
#define PININT_ISEL_RESERVED (~0xff)
#define PININT_IENR_RESERVED (~0xff)
#define PININT_SIENR_RESERVED (~0xff)
#define PININT_CIENR_RESERVED (~0xff)
#define PININT_IENF_RESERVED (~0xff)
#define PININT_SIENF_RESERVED (~0xff)
#define PININT_CIENF_RESERVED (~0xff)
#define PININT_RISE_RESERVED (~0xff)
#define PININT_FALL_RESERVED (~0xff)
#define PININT_IST_RESERVED (~0xff)
#define PININT_PMCTRL_RESERVED (~0xff000003)
#define PININT_PMSRC_RESERVED 0xff
#define PININT_PMCFG_RESERVED (1<<7)
/**
* LPC8xx Pin Interrupt and Pattern match engine register
* bit fields and macros
*/
/* PININT interrupt control register */
#define PININT_PMCTRL_PMATCH_SEL (1 << 0)
#define PININT_PMCTRL_RXEV_ENA (1 << 1)
/* PININT Bit slice source register bits */
#define PININT_SRC_BITSOURCE_START 8
#define PININT_SRC_BITSOURCE_MASK 7
/* PININT Bit slice configuration register bits */
#define PININT_SRC_BITCFG_START 8
#define PININT_SRC_BITCFG_MASK 7
/**
* LPC8xx Pin Interrupt channel values
*/
#define PININTCH0 (1 << 0)
#define PININTCH1 (1 << 1)
#define PININTCH2 (1 << 2)
#define PININTCH3 (1 << 3)
#define PININTCH4 (1 << 4)
#define PININTCH5 (1 << 5)
#define PININTCH6 (1 << 6)
#define PININTCH7 (1 << 7)
#define PININTCH(ch) (1 << (ch))
/**
* LPC8xx Pin Matching Interrupt bit slice enum values
*/
typedef enum Chip_PININT_BITSLICE {
PININTBITSLICE0 = 0, /*!< PININT Bit slice 0 */
PININTBITSLICE1 = 1, /*!< PININT Bit slice 1 */
PININTBITSLICE2 = 2, /*!< PININT Bit slice 2 */
PININTBITSLICE3 = 3, /*!< PININT Bit slice 3 */
PININTBITSLICE4 = 4, /*!< PININT Bit slice 4 */
PININTBITSLICE5 = 5, /*!< PININT Bit slice 5 */
PININTBITSLICE6 = 6, /*!< PININT Bit slice 6 */
PININTBITSLICE7 = 7 /*!< PININT Bit slice 7 */
} Chip_PININT_BITSLICE_T;
/**
* LPC8xx Pin Matching Interrupt bit slice configuration enum values
*/
typedef enum Chip_PININT_BITSLICE_CFG {
PININT_PATTERNCONST1 = 0x0, /*!< Contributes to product term match */
PININT_PATTERNRISING = 0x1, /*!< Rising edge */
PININT_PATTERNFALLING = 0x2, /*!< Falling edge */
PININT_PATTERNRISINGRFALLING = 0x3, /*!< Rising or Falling edge */
PININT_PATTERNHIGH = 0x4, /*!< High level */
PININT_PATTERNLOW = 0x5, /*!< Low level */
PININT_PATTERCONST0 = 0x6, /*!< Never contributes for match */
PININT_PATTEREVENT = 0x7 /*!< Match occurs on event */
} Chip_PININT_BITSLICE_CFG_T;
/**
* @brief Initialize Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
* @note This function should be used after the Chip_GPIO_Init() function.
*/
STATIC INLINE void Chip_PININT_Init(LPC_PININT_T *pPININT) {}
/**
* @brief De-Initialize Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DeInit(LPC_PININT_T *pPININT) {}
/**
* @brief Configure the pins as edge sensitive in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_SetPinModeEdge(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->ISEL &= ~(pins | PININT_ISEL_RESERVED);
}
/**
* @brief Configure the pins as level sensitive in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_SetPinModeLevel(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->ISEL = pins | (pPININT->ISEL & ~PININT_ISEL_RESERVED);
pPININT->SIENR = pins;
}
/**
* @brief Return current PININT rising edge or high level interrupt enable state
* @param pPININT : The base address of Pin interrupt block
* @return A bifield containing the high edge/level interrupt enables for each
* interrupt. Bit 0 = PININT0, 1 = PININT1, etc.
* For each bit, a 0 means the high edge/level interrupt is disabled, while a 1
* means it's enabled.
*/
STATIC INLINE uint32_t Chip_PININT_GetHighEnabled(LPC_PININT_T *pPININT)
{
return pPININT->IENR & ~PININT_IENR_RESERVED;
}
/**
* @brief Enable high edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to enable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnableIntHigh(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->SIENR = pins;
}
/**
* @brief Select high/low level for level sensitive PININT interrupts
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to enable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_SelectLevel(LPC_PININT_T *pPININT, uint32_t pins, bool isHigh)
{
if (isHigh)
pPININT->SIENF = pins;
else
pPININT->CIENF = pins;
}
/**
* @brief Disable high edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to disable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisableIntHigh(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->CIENR = pins;
}
/**
* @brief Return current PININT falling edge or low level interrupt enable state
* @param pPININT : The base address of Pin interrupt block
* @return A bifield containing the low edge/level interrupt enables for each
* interrupt. Bit 0 = PININT0, 1 = PININT1, etc.
* For each bit, a 0 means the low edge/level interrupt is disabled, while a 1
* means it's enabled.
*/
STATIC INLINE uint32_t Chip_PININT_GetLowEnabled(LPC_PININT_T *pPININT)
{
return pPININT->IENF & ~PININT_IENF_RESERVED;
}
/**
* @brief Enable low edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to enable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnableIntLow(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->SIENF = pins;
}
/**
* @brief Disable low edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to disable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisableIntLow(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->CIENF = pins;
}
/**
* @brief Return pin states that have a detected latched high edge (RISE) state
* @param pPININT : The base address of Pin interrupt block
* @return PININT states (bit n = high) with a latched rise state detected
*/
STATIC INLINE uint32_t Chip_PININT_GetRiseStates(LPC_PININT_T *pPININT)
{
return pPININT->RISE & ~PININT_RISE_RESERVED;
}
/**
* @brief Clears pin states that had a latched high edge (RISE) state
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins with latched states to clear
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearRiseStates(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->RISE = pins;
}
/**
* @brief Return pin states that have a detected latched falling edge (FALL) state
* @param pPININT : The base address of Pin interrupt block
* @return PININT states (bit n = high) with a latched rise state detected
*/
STATIC INLINE uint32_t Chip_PININT_GetFallStates(LPC_PININT_T *pPININT)
{
return pPININT->FALL & ~PININT_FALL_RESERVED;
}
/**
* @brief Clears pin states that had a latched falling edge (FALL) state
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins with latched states to clear
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearFallStates(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->FALL = pins;
}
/**
* @brief Get interrupt status from Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Interrupt status (bit n for PININTn = high means interrupt ie pending)
*/
STATIC INLINE uint32_t Chip_PININT_GetIntStatus(LPC_PININT_T *pPININT)
{
return pPININT->IST& ~PININT_IST_RESERVED;
}
/**
* @brief Clear interrupt status in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pin interrupts to clear (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearIntStatus(LPC_PININT_T *pPININT, uint32_t pins)
{
pPININT->IST = pins;
}
/**
* @brief Set source for pattern match in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param chan : PININT channel number (From 0 to 7)
* @param slice : PININT slice number
* @return Nothing
*/
void Chip_PININT_SetPatternMatchSrc(LPC_PININT_T *pPININT, uint8_t chan, Chip_PININT_BITSLICE_T slice);
/**
* @brief Configure the pattern matcch in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param slice : PININT slice number
* @param slice_cfg : PININT slice configuration value (enum Chip_PININT_BITSLICE_CFG_T)
* @param end_point : If true, current slice is final component
* @return Nothing
*/
void Chip_PININT_SetPatternMatchConfig(LPC_PININT_T *pPININT, Chip_PININT_BITSLICE_T slice,
Chip_PININT_BITSLICE_CFG_T slice_cfg, bool end_point);
/**
* @brief Enable pattern match interrupts in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnablePatternMatch(LPC_PININT_T *pPININT)
{
pPININT->PMCTRL = PININT_PMCTRL_PMATCH_SEL | (pPININT->PMCTRL & ~PININT_PMCTRL_RESERVED);
}
/**
* @brief Disable pattern match interrupts in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisablePatternMatch(LPC_PININT_T *pPININT)
{
pPININT->PMCTRL &= ~(PININT_PMCTRL_PMATCH_SEL | PININT_PMCTRL_RESERVED);
}
/**
* @brief Enable RXEV output in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnablePatternMatchRxEv(LPC_PININT_T *pPININT)
{
pPININT->PMCTRL = PININT_PMCTRL_RXEV_ENA | (pPININT->PMCTRL & ~PININT_PMCTRL_RESERVED);
}
/**
* @brief Disable RXEV output in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisablePatternMatchRxEv(LPC_PININT_T *pPININT)
{
pPININT->PMCTRL &= ~(PININT_PMCTRL_RXEV_ENA | PININT_PMCTRL_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __PININT_8XX_H_ */

View File

@ -0,0 +1,109 @@
/*
* @brief LPC8xx PMU chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Reserved bits mask for SCR register */
#define SCB_SCR_RESERVED (~(SCB_SCR_SLEEPONEXIT_Msk|SCB_SCR_SLEEPDEEP_Msk|SCB_SCR_SEVONPEND_Msk))
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Enter MCU Sleep mode */
void Chip_PMU_SleepState(LPC_PMU_T *pPMU)
{
SCB->SCR = ~(1UL << SCB_SCR_SLEEPDEEP_Pos) & (SCB->SCR & ~SCB_SCR_RESERVED);
pPMU->PCON = PMU_PCON_PM_SLEEP;
/* Enter sleep mode */
__WFI();
}
/* Enter MCU Deep Sleep mode */
void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU)
{
SCB->SCR = (1UL << SCB_SCR_SLEEPDEEP_Pos) | (SCB->SCR & ~SCB_SCR_RESERVED);
pPMU->PCON = PMU_PCON_PM_DEEPSLEEP;
/* Enter sleep mode */
__WFI();
}
/* Enter MCU Power down mode */
void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU)
{
SCB->SCR = (1UL << SCB_SCR_SLEEPDEEP_Pos) | (SCB->SCR & ~SCB_SCR_RESERVED);
pPMU->PCON = PMU_PCON_PM_POWERDOWN;
/* Enter sleep mode */
__WFI();
}
/* Enter MCU Deep Power down mode */
void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU)
{
SCB->SCR = (1UL << SCB_SCR_SLEEPDEEP_Pos) | (SCB->SCR & ~SCB_SCR_RESERVED);
pPMU->PCON = PMU_PCON_PM_DEEPPOWERDOWN;
/* Enter sleep mode */
__WFI();
}
/* Put some of the peripheral in sleep mode */
void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode)
{
if (SleepMode == PMU_MCU_DEEP_SLEEP) {
Chip_PMU_DeepSleepState(pPMU);
}
else if (SleepMode == PMU_MCU_POWER_DOWN) {
Chip_PMU_PowerDownState(pPMU);
}
else if (SleepMode == PMU_MCU_DEEP_PWRDOWN) {
Chip_PMU_DeepPowerDownState(pPMU);
}
else {
/* PMU_MCU_SLEEP */
Chip_PMU_SleepState(pPMU);
}
}

View File

@ -0,0 +1,237 @@
/*
* @brief LPC8xx PMU chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __PMU_8XX_H_
#define __PMU_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup PMU_8XX CHIP: LPC8xx PMU driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx Power Management Unit register block structure
*/
typedef struct {
__IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */
__IO uint32_t GPREG[4]; /*!< Offset: 0x004 General purpose Registers 0..3 (R/W) */
__IO uint32_t DPDCTRL; /*!< Offset: 0x014 Deep power-down control register (R/W) */
} LPC_PMU_T;
/* Reserved bits masks for registers */
#define PMU_PCON_RESERVED ((0xf<<4)|(0x6<<8)|0xfffff000)
#define PMU_DPDCTRL_RESERVED (~0xf)
/**
* @brief LPC8xx low power mode type definitions
*/
typedef enum CHIP_PMU_MCUPOWER {
PMU_MCU_SLEEP = 0, /*!< Sleep mode */
PMU_MCU_DEEP_SLEEP, /*!< Deep Sleep mode */
PMU_MCU_POWER_DOWN, /*!< Power down mode */
PMU_MCU_DEEP_PWRDOWN /*!< Deep power down mode */
} CHIP_PMU_MCUPOWER_T;
/**
* PMU PCON register bit fields & masks
*/
#define PMU_PCON_PM_SLEEP (0x0) /*!< ARM WFI enter sleep mode */
#define PMU_PCON_PM_DEEPSLEEP (0x1) /*!< ARM WFI enter Deep-sleep mode */
#define PMU_PCON_PM_POWERDOWN (0x2) /*!< ARM WFI enter Power-down mode */
#define PMU_PCON_PM_DEEPPOWERDOWN (0x3) /*!< ARM WFI enter Deep Power-down mode */
#define PMU_PCON_NODPD (1 << 3) /*!< Disable deep power-down mode */
#define PMU_PCON_SLEEPFLAG (1 << 8) /*!< Sleep mode flag */
#define PMU_PCON_DPDFLAG (1 << 11) /*!< Deep power-down flag */
/**
* PMU DPDCTRL register bit fields & masks
*/
#define PMU_DPDCTRL_WAKEUPPHYS (1 << 0) /** Enable wake-up pin hysteresis */
#define PMU_DPDCTRL_WAKEPAD (1 << 1) /** Disable the Wake-up */
#define PMU_DPDCTRL_LPOSCEN (1 << 2) /** Enable the low-power oscillator (10 khz self wk) */
#define PMU_DPDCTRL_LPOSCDPDEN (1 << 3) /** Enable the low-power oscillator in deep power-down*/
/**
* @brief Write a value to a GPREG register
* @param pPMU : Pointer to PMU register block
* @param regIndex : Register index to write to, must be 0..3
* @param value : Value to write
* @return None
*/
STATIC INLINE void Chip_PMU_WriteGPREG(LPC_PMU_T *pPMU, uint8_t regIndex, uint32_t value)
{
pPMU->GPREG[regIndex] = value;
}
/**
* @brief Read a value to a GPREG register
* @param pPMU : Pointer to PMU register block
* @param regIndex : Register index to read from, must be 0..3
* @return Value read from the GPREG register
*/
STATIC INLINE uint32_t Chip_PMU_ReadGPREG(LPC_PMU_T *pPMU, uint8_t regIndex)
{
return pPMU->GPREG[regIndex];
}
/**
* @brief Enter MCU Sleep mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note The sleep mode affects the ARM Cortex-M0+ core only. Peripherals
* and memories are active.
*/
void Chip_PMU_SleepState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Deep Sleep mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note In Deep-sleep mode, the peripherals receive no internal clocks.
* The flash is in stand-by mode. The SRAM memory and all peripheral registers
* as well as the processor maintain their internal states. The WWDT, WKT,
* and BOD can remain active to wake up the system on an interrupt.
*/
void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Power down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note In Power-down mode, the peripherals receive no internal clocks.
* The internal SRAM memory and all peripheral registers as well as the
* processor maintain their internal states. The flash memory is powered
* down. The WWDT, WKT, and BOD can remain active to wake up the system
* on an interrupt.
*/
void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Deep Power down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note For maximal power savings, the entire system is shut down
* except for the general purpose registers in the PMU and the self
* wake-up timer. Only the general purpose registers in the PMU maintain
* their internal states. The part can wake up on a pulse on the WAKEUP
* pin or when the self wake-up timer times out. On wake-up, the part
* reboots.
*/
void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU);
/**
* @brief Place the MCU in a low power state
* @param pPMU : Pointer to PMU register block
* @param SleepMode : Sleep mode
* @return None
*/
void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode);
/**
* @brief Disables deep power-down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note Calling this functions prevents entry to Deep power-down
* mode. Once set, this can only be cleared by power-on reset.
*/
STATIC INLINE void Chip_PMU_DisableDeepPowerDown(LPC_PMU_T *pPMU)
{
pPMU->PCON = PMU_PCON_NODPD | (pPMU->PCON & ~PMU_PCON_RESERVED);
}
/**
* @brief Returns sleep/power-down flags
* @param pPMU : Pointer to PMU register block
* @return Or'ed values of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
* @note These indicate that the PMU is setup for entry into a low
* power state on the next WFI() instruction.
*/
STATIC INLINE uint32_t Chip_PMU_GetSleepFlags(LPC_PMU_T *pPMU)
{
return (pPMU->PCON & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG));
}
/**
* @brief Clears sleep/power-down flags
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
* @return Nothing
* @note Use this function to clear a low power state prior to calling
* WFI().
*/
STATIC INLINE void Chip_PMU_ClearSleepFlags(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->PCON |= (flags & (~PMU_PCON_RESERVED));
}
/**
* @brief Sets deep power-down functions
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_DPDCTRL_* values
* @return Nothing
* @note Some of these functions may need to be set prior to going
* into a low power mode. Note that some calls to this function enable
* functions while others disable it based on the PMU_DPDCTRL_*
* definitions.
*/
STATIC INLINE void Chip_PMU_SetPowerDownControl(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->DPDCTRL = flags | (pPMU->DPDCTRL & ~PMU_DPDCTRL_RESERVED);
}
/**
* @brief Cleats deep power-down functions
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_DPDCTRL_* values
* @return Nothing
* @note Some of these functions may need to be cleared prior to going
* into a low power mode. Note that some calls to this function enable
* functions while others disable it based on the PMU_DPDCTRL_*
* definitions.
*/
STATIC INLINE void Chip_PMU_ClearPowerDownControl(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->DPDCTRL &= ~(flags | PMU_DPDCTRL_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __PMU_8XX_H_ */

View File

@ -0,0 +1,125 @@
/*
* @brief LPC8xx I2C ROM API declarations and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ROM_I2C_8XX_H_
#define __ROM_I2C_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CHIP_I2CROM_8XX CHIP: LPC8xx I2C ROM API declarations and functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx I2C ROM driver handle structure
*/
typedef void *I2C_HANDLE_T;
/**
* @brief LPC8xx I2C ROM driver callback function
*/
typedef void (*I2C_CALLBK_T)(uint32_t err_code, uint32_t n);
/**
* LPC8xx I2C ROM driver parameter structure
*/
typedef struct I2C_PARAM {
uint32_t num_bytes_send; /*!< No. of bytes to send */
uint32_t num_bytes_rec; /*!< No. of bytes to receive */
uint8_t *buffer_ptr_send; /*!< Pointer to send buffer */
uint8_t *buffer_ptr_rec; /*!< Pointer to receive buffer */
I2C_CALLBK_T func_pt; /*!< Callback function */
uint8_t stop_flag; /*!< Stop flag */
uint8_t dummy[3];
} I2C_PARAM_T;
/**
* LPC8xx I2C ROM driver result structure
*/
typedef struct I2C_RESULT {
uint32_t n_bytes_sent; /*!< No. of bytes sent */
uint32_t n_bytes_recd; /*!< No. of bytes received */
} I2C_RESULT_T;
/**
* LPC8xx I2C ROM driver modes enum
*/
typedef enum CHIP_I2C_MODE {
IDLE, /*!< IDLE state */
MASTER_SEND, /*!< Master send state */
MASTER_RECEIVE, /*!< Master Receive state */
SLAVE_SEND, /*!< Slave send state */
SLAVE_RECEIVE /*!< Slave receive state */
} CHIP_I2C_MODE_T;
/**
* LPC8xx I2C ROM driver APIs structure
*/
typedef struct I2CD_API {
/*!< Interrupt Support Routine */
void (*i2c_isr_handler)(I2C_HANDLE_T *handle);
/*!< MASTER functions */
ErrorCode_t (*i2c_master_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_tx_rx_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_tx_rx_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
/*!< SLAVE functions */
ErrorCode_t (*i2c_slave_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_set_slave_addr)(I2C_HANDLE_T *handle, uint32_t slave_addr_0_3, uint32_t slave_mask_0_3);
/*!< OTHER support functions */
uint32_t (*i2c_get_mem_size)(void);
I2C_HANDLE_T * (*i2c_setup)( uint32_t i2c_base_addr, uint32_t * start_of_ram);
ErrorCode_t (*i2c_set_bitrate)(I2C_HANDLE_T *handle, uint32_t p_clk_in_hz, uint32_t bitrate_in_bps);
uint32_t (*i2c_get_firmware_version)(void);
CHIP_I2C_MODE_T (*i2c_get_status)(I2C_HANDLE_T *handle);
ErrorCode_t (*i2c_set_timeout)(I2C_HANDLE_T *handle, uint32_t timeout);
} I2CD_API_T;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ROM_I2C_8XX_H_ */

View File

@ -0,0 +1,92 @@
/*
* @brief LPC8xx Power ROM API declarations and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ROM_PWR_8XX_H_
#define __ROM_PWR_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup PWRD_8XX CHIP: LPC8xx Power ROM API declarations and functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx Power ROM APIs - set_pll mode options
*/
#define CPU_FREQ_EQU 0
#define CPU_FREQ_LTE 1
#define CPU_FREQ_GTE 2
#define CPU_FREQ_APPROX 3
/**
* @brief LPC8xx Power ROM APIs - set_pll response0 options
*/
#define PLL_CMD_SUCCESS 0
#define PLL_INVALID_FREQ 1
#define PLL_INVALID_MODE 2
#define PLL_FREQ_NOT_FOUND 3
#define PLL_NOT_LOCKED 4
/**
* @brief LPC8xx Power ROM APIs - set_power mode options
*/
#define PWR_DEFAULT 0
#define PWR_CPU_PERFORMANCE 1
#define PWR_EFFICIENCY 2
#define PWR_LOW_CURRENT 3
/**
* @brief LPC8xx Power ROM APIs - set_power response0 options
*/
#define PWR_CMD_SUCCESS 0
#define PWR_INVALID_FREQ 1
#define PWR_INVALID_MODE 2
/**
* @brief LPC8XX Power ROM API structure
*/
typedef struct PWRD_API {
void (*set_pll)(uint32_t cmd[], uint32_t resp[]); /*!< Set PLL function */
void (*set_power)(uint32_t cmd[], uint32_t resp[]); /*!< Set power function */
} PWRD_API_T;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ROM_PWR_8XX_H_ */

View File

@ -0,0 +1,180 @@
/*
* @brief LPC8xx UART ROM API declarations and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ROM_UART_8XX_H_
#define __ROM_UART_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup UARTROM_8XX CHIP: LPC8xx UART ROM API declarations and functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief UART ROM driver - UART errors in UART configuration used in uart_init function
*/
#define OVERRUN_ERR_EN (1 << 0) /*!< Bit 0: Enable overrun error */
#define UNDERRUN_ERR_EN (1 << 1) /*!< Bit 1: Enable underrun error */
#define FRAME_ERR_EN (1 << 2) /*!< Bit 2: enable frame error */
#define PARITY_ERR_EN (1 << 3) /*!< Bit 3: enable parity error */
#define RXNOISE_ERR_EN (1 << 4) /*!< Bit 4: enable receive noise error */
/**
* Macros for UART errors
*/
/*!< Enable all the UART errors */
#define ALL_ERR_EN (OVERRUN_ERR_EN | UNDERRUN_ERR_EN | FRAME_ERR_EN | PARITY_ERR_EN | \
RXNOISE_ERR_EN)
/*!< Disable all the errors */
#define NO_ERR_EN (0)
/**
* Transfer mode values in UART parameter structure.
* Used in uart_get_line & uart_put_line function
*/
/*!< 0x00: uart_get_line: stop transfer when the buffer is full */
/*!< 0x00: uart_put_line: stop transfer when the buffer is empty */
#define TX_MODE_BUF_EMPTY (0x00)
#define RX_MODE_BUF_FULL (0x00)
/*!< 0x01: uart_get_line: stop transfer when CRLF are received */
/*!< 0x01: uart_put_line: transfer stopped after reaching \0 and CRLF is sent out after that */
#define TX_MODE_SZERO_SEND_CRLF (0x01)
#define RX_MODE_CRLF_RECVD (0x01)
/*!< 0x02: uart_get_line: stop transfer when LF are received */
/*!< 0x02: uart_put_line: transfer stopped after reaching \0. And LF is sent out after that */
#define TX_MODE_SZERO_SEND_LF (0x02)
#define RX_MODE_LF_RECVD (0x02)
/*!< 0x03: uart_get_line: RESERVED */
/*!< 0x03: uart_put_line: transfer stopped after reaching \0 */
#define TX_MODE_SZERO (0x03)
/**
* @brief UART ROM driver modes
*/
#define DRIVER_MODE_POLLING (0x00) /*!< Polling mode */
#define DRIVER_MODE_INTERRUPT (0x01) /*!< Interrupt mode */
#define DRIVER_MODE_DMA (0x02) /*!< DMA mode */
/**
* @brief UART ROM driver UART handle
*/
typedef void UART_HANDLE_T;
/**
* @brief UART ROM driver UART callback function
*/
typedef void (*UART_CALLBK_T)(uint32_t err_code, uint32_t n);
/**
* @brief UART ROM driver UART DMA callback function
*/
typedef void (*UART_DMA_REQ_T)(uint32_t src_adr, uint32_t dst_adr, uint32_t size);
/**
* @brief UART ROM driver configutaion structure
*/
typedef struct {
uint32_t sys_clk_in_hz; /*!< main clock in Hz */
uint32_t baudrate_in_hz; /*!< Baud rate in Hz */
uint8_t config; /*!< Configuration value */
/*!< bit1:0 Data Length: 00: 7 bits length, 01: 8 bits length, others: reserved */
/*!< bit3:2 Parity: 00: No Parity, 01: reserved, 10: Even, 11: Odd */
/*!< bit4: Stop Bit(s): 0: 1 Stop bit, 1: 2 Stop bits */
uint8_t sync_mod; /*!< Sync mode settings */
/*!< bit0: Mode: 0: Asynchronous mode, 1: Synchronous mode */
/*!< bit1: 0: Un_RXD is sampled on the falling edge of SCLK */
/*!< 1: Un_RXD is sampled on the rising edge of SCLK */
/*!< bit2: 0: Start and stop bits are transmitted as in asynchronous mode) */
/*!< 1: Start and stop bits are not transmitted) */
/*!< bit3: 0: The UART is a slave in Synchronous mode */
/*!< 1: The UART is a master in Synchronous mode */
uint16_t error_en; /*!< Errors to be enabled */
/*!< bit0: Overrun Errors Enabled */
/*!< bit1: Underrun Errors Enabled */
/*!< bit2: FrameErr Errors Enabled */
/*!< bit3: ParityErr Errors Enabled */
/*!< bit4: RxNoise Errors Enabled */
} UART_CONFIG_T;
/**
* @brief UART ROM driver parameter structure
*/
typedef struct {
uint8_t *buffer; /*!< Pointer to data buffer */
uint32_t size; /*!< Size of the buffer */
uint16_t transfer_mode; /*!< Transfer mode settings */
/*!< 0x00: uart_get_line: stop transfer when the buffer is full */
/*!< 0x00: uart_put_line: stop transfer when the buffer is empty */
/*!< 0x01: uart_get_line: stop transfer when CRLF are received */
/*!< 0x01: uart_put_line: transfer stopped after reaching \0 and CRLF is sent out after that */
/*!< 0x02: uart_get_line: stop transfer when LF are received */
/*!< 0x02: uart_put_line: transfer stopped after reaching \0 and LF is sent out after that */
/*!< 0x03: uart_get_line: RESERVED */
/*!< 0x03: uart_put_line: transfer stopped after reaching \0 */
uint16_t driver_mode; /*!< Driver mode */
/*!< 0x00: Polling mode, function blocked until transfer completes */
/*!< 0x01: Interrupt mode, function immediately returns, callback invoked when transfer completes */
/*!< 0x02: DMA mode, in case DMA block is available, DMA req function is called for UART DMA channel setup, then callback function indicate that transfer completes */
UART_CALLBK_T callback_func_pt; /*!< callback function pointer */
UART_DMA_REQ_T dma_req_func_pt; /*!< UART DMA channel setup function pointer, not applicable on LPC8xx */
} UART_PARAM_T;
/**
* @brief UART ROM driver APIs structure
*/
typedef struct UARTD_API {
/*!< UART Configuration functions */
uint32_t (*uart_get_mem_size)(void); /*!< Get the memory size needed by one Min UART instance */
UART_HANDLE_T * (*uart_setup)(uint32_t base_addr, uint8_t * ram); /*!< Setup Min UART instance with provided memory and return the handle to this instance */
uint32_t (*uart_init)(UART_HANDLE_T *handle, UART_CONFIG_T *set); /*!< Setup baud rate and operation mode for uart, then enable uart */
/*!< UART polling functions block until completed */
uint8_t (*uart_get_char)(UART_HANDLE_T *handle); /*!< Receive one Char from uart. This functions is only returned after Char is received. In case Echo is enabled, the received data is sent out immediately */
void (*uart_put_char)(UART_HANDLE_T *handle, uint8_t data); /*!< Send one Char through uart. This function is only returned after data is sent */
uint32_t (*uart_get_line)(UART_HANDLE_T *handle, UART_PARAM_T *param); /*!< Receive multiple bytes from UART */
uint32_t (*uart_put_line)(UART_HANDLE_T *handle, UART_PARAM_T *param); /*!< Send string (end with \0) or raw data through UART */
/*!< UART interrupt functions return immediately and callback when completed */
void (*uart_isr)(UART_HANDLE_T *handle); /*!< UART interrupt service routine. To use this routine, the corresponding USART interrupt must be enabled. This function is invoked by the user ISR */
} UARTD_API_T;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ROM_UART_8XX_H_ */

View File

@ -0,0 +1,96 @@
/*
* @brief LPC8xx ROM API declarations and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ROMAPI_8XX_H_
#define __ROMAPI_8XX_H_
#include "../iap/iap.h"
#include "../../common/chip/error_8xx.h"
#include "rom_i2c_8xx.h"
#include "rom_pwr_8xx.h"
#include "rom_uart_8xx.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup ROMAPI_8XX CHIP: LPC8xx ROM API declarations and functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8XX High level ROM API structure
*/
typedef struct ROM_API {
const uint32_t unused[3];
const PWRD_API_T *pPWRD; /*!< Power profiles API function table */
const uint32_t p_dev1;
const I2CD_API_T *pI2CD; /*!< I2C driver routines functions table */
const uint32_t p_dev3;
const uint32_t p_dev4;
const uint32_t p_dev5;
const UARTD_API_T *pUARTD; /*!< UART driver routines function table */
} LPC_ROM_API_T;
/* Pointer to ROM API function address */
#define LPC_ROM_API_BASE_LOC 0x1FFF1FF8UL
#define LPC_ROM_API (*(LPC_ROM_API_T * *) LPC_ROM_API_BASE_LOC)
/* Pointer to @ref PWRD_API_T functions in ROM */
#define LPC_PWRD_API ((LPC_ROM_API)->pPWRD)
/* Pointer to @ref I2CD_API_T functions in ROM */
#define LPC_I2CD_API ((LPC_ROM_API)->pI2CD)
/* Pointer to @ref UARTD_API_T functions in ROM */
#define LPC_UARTD_API ((LPC_ROM_API)->pUARTD)
/* Pointer to ROM IAP entry functions */
#define IAP_ENTRY_LOCATION 0X1FFF1FF1UL
/**
* @brief LPC8XX IAP_ENTRY API function type
*/
static INLINE void iap_entry(unsigned int cmd_param[], unsigned int status_result[])
{
((IAP_ENTRY_T) IAP_ENTRY_LOCATION)(cmd_param, status_result);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ROMAPI_8XX_H_ */

View File

@ -0,0 +1,81 @@
/*
* @brief LPC8xx State Configurable Timer driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize SCT */
void Chip_SCT_Init(LPC_SCT_T *pSCT)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SCT);
Chip_SYSCTL_PeriphReset(RESET_SCT);
}
/* Shutdown SCT */
void Chip_SCT_DeInit(LPC_SCT_T *pSCT)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SCT);
}
/* Set/Clear SCT control register */
void Chip_SCT_SetClrControl(LPC_SCT_T *pSCT, uint32_t value, FunctionalState ena)
{
if (ena == ENABLE) {
Chip_SCT_SetControl(pSCT, value);
}
else {
Chip_SCT_ClearControl(pSCT, value);
}
}
/* Set Conflict resolution */
void Chip_SCT_SetConflictResolution(LPC_SCT_T *pSCT, uint8_t outnum, uint8_t value)
{
uint32_t tem;
tem = pSCT->RES & ~((0x03 << (2 * outnum))|SCT_RES_RESERVED);
pSCT->RES = tem | (value << (2 * outnum));
}

View File

@ -0,0 +1,458 @@
/*
* @brief LPC8xx State Configurable Timer (SCT) Chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SCT_8XX_H_
#define __SCT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup SCT_8XX CHIP: LPC8xx State Configurable Timer driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/*
* @brief SCT Module configuration
*/
#define CONFIG_SCT_nEV (8) /*!< Number of events */
#define CONFIG_SCT_nRG (8) /*!< Number of match/compare registers */
#define CONFIG_SCT_nOU (6) /*!< Number of outputs */
/**
* @brief State Configurable Timer register block structure
*/
typedef struct {
__IO uint32_t CONFIG; /*!< configuration Register (offset (0x000) */
union {
__IO uint32_t CTRL_U; /*!< control Register */
struct {
__IO uint16_t CTRL_L; /*!< low control register */
__IO uint16_t CTRL_H; /*!< high control register */
};
};
union {
__IO uint32_t LIMIT_U; /*!< limit Register */
struct {
__IO uint16_t LIMIT_L; /*!< limit register for counter L */
__IO uint16_t LIMIT_H; /*!< limit register for counter H */
};
};
union {
__IO uint32_t HALT_U; /*!< halt Register */
struct {
__IO uint16_t HALT_L; /*!< halt register for counter L */
__IO uint16_t HALT_H; /*!< halt register for counter H */
};
};
union {
__IO uint32_t STOP_U; /*!< stop Register */
struct {
__IO uint16_t STOP_L; /*!< stop register for counter L */
__IO uint16_t STOP_H; /*!< stop register for counter H */
};
};
union {
__IO uint32_t START_U; /*!< start Register */
struct {
__IO uint16_t START_L; /*!< start register for counter L */
__IO uint16_t START_H; /*!< start register for counter H */
};
};
uint32_t RESERVED1[10]; /*!< 0x018 - 0x03C reserved */
union {
__IO uint32_t COUNT_U; /*!< counter register (offset 0x040)*/
struct {
__IO uint16_t COUNT_L; /*!< counter register for counter L */
__IO uint16_t COUNT_H; /*!< counter register for counter H */
};
};
union {
__IO uint32_t STATE_U; /*!< State register */
struct {
__IO uint16_t STATE_L; /*!< state register for counter L */
__IO uint16_t STATE_H; /*!< state register for counter H */
};
};
__I uint32_t INPUT; /*!< input register */
union {
__IO uint32_t REGMODE_U; /*!< RegMode register */
struct {
__IO uint16_t REGMODE_L; /*!< match - capture registers mode register L */
__IO uint16_t REGMODE_H; /*!< match - capture registers mode register H */
};
};
__IO uint32_t OUTPUT; /*!< output register */
__IO uint32_t OUTPUTDIRCTRL; /*!< output counter direction Control Register */
__IO uint32_t RES; /*!< conflict resolution register */
__IO uint32_t DMAREQ0; /*!< DMA0 Request Register */
__IO uint32_t DMAREQ1; /*!< DMA1 Request Register */
uint32_t RESERVED2[35]; /*!< 0x064 - 0x0EC reserved */
__IO uint32_t EVEN; /*!< event enable register (offset 0x0F0)*/
__IO uint32_t EVFLAG; /*!< event flag register */
__IO uint32_t CONEN; /*!< conflict enable register */
__IO uint32_t CONFLAG; /*!< conflict flag register */
union {
__IO union { /*!< ... Match / Capture value */
uint32_t U; /*!< MATCH[i].U Unified 32-bit register */
struct {
uint16_t L; /*!< MATCH[i].L Access to L value */
uint16_t H; /*!< MATCH[i].H Access to H value */
};
} MATCH[CONFIG_SCT_nRG];
__I union {
uint32_t U; /*!< CAP[i].U Unified 32-bit register */
struct {
uint16_t L; /*!< CAP[i].L Access to L value */
uint16_t H; /*!< CAP[i].H Access to H value */
};
} CAP[CONFIG_SCT_nRG];
};
uint32_t RESERVED3[56]; /*!< 0x120 - 0x1FC reserved */
union {
__IO union { /*!< ...Match Reload / Capture Control value (offset 0x200) */
uint32_t U; /*!< MATCHREL[i].U Unified 32-bit register */
struct {
uint16_t L; /*!< MATCHREL[i].L Access to L value */
uint16_t H; /*!< MATCHREL[i].H Access to H value */
};
} MATCHREL[CONFIG_SCT_nRG];
__IO union {
uint32_t U; /*!< CAPCTRL[i].U Unified 32-bit register */
struct {
uint16_t L; /*!< CAPCTRL[i].L Access to L value */
uint16_t H; /*!< CAPCTRL[i].H Access to H value */
};
} CAPCTRL[CONFIG_SCT_nRG];
};
uint32_t RESERVED4[56]; /*!< 0x220 - 0x2FC reserved */
__IO struct { /*!< EV[i].STATE / EV[i].CTRL (offset 0x300) */
uint32_t STATE; /*!< Event State Register */
uint32_t CTRL; /*!< Event Control Register */
} EV[CONFIG_SCT_nEV];
uint32_t RESERVED5[112]; /*!< 0x340 - 0x4FC reserved */
__IO struct { /*!< OUT[i].SET / OUT[i].CLR (offset 0x500) */
uint32_t SET; /*!< Output n Set Register */
uint32_t CLR; /*!< Output n Clear Register */
} OUT[CONFIG_SCT_nOU];
} LPC_SCT_T;
/* Reserved bits masks for registers */
#define SCT_CONFIG_RESERVED 0xfff80000
#define SCT_CTRL_RESERVED ((7<<13)|(7u<<29))
#define SCT_LIMIT_RESERVED (~(0x3f|(0x3f<<16))
#define SCT_HALT_RESERVED (~(0x3f|(0x3f<<16))
#define SCT_STOP_RESERVED (~(0x3f|(0x3f<<16))
#define SCT_START_RESERVED (~(0x3f|(0x3f<<16))
#define SCT_STATE_RESERVED (~(0x1f|(0x1f<<16))
#define SCT_INPUT_RESERVED (~(0xf|(0xf<<16))
#define SCT_REGMODE_RESERVED (~(0x1f|(0x1f<<16))
#define SCT_OUTPUT_RESERVED (~0xf)
#define SCT_OUTPUTDIRCTRL_RESERVED (~0xff)
#define SCT_RES_RESERVED (~0xff)
#define SCT_EVEN_RESERVED (~0x3f)
#define SCT_EVFLAG_RESERVED (~0x3f)
#define SCT_CONEN_RESERVED (~0xf)
#define SCT_CONFLAG_RESERVED (~(0xf|(3u<<30)))
#define SCT_CAPCTRL_RESERVED (~(0x3f|(0x3f<<16)))
#define SCT_EVn_STATE_RESERVED (~3)
#define SCT_EVn_CTRL_RESERVED (0xff800000)
#define SCT_OUTn_SET_RESERVED (~0x3f)
#define SCT_OUTn_CLR_RESERVED (~0x3f)
/*
* @brief Macro defines for SCT configuration register
*/
#define SCT_CONFIG_16BIT_COUNTER 0x00000000 /*!< Operate as 2 16-bit counters */
#define SCT_CONFIG_32BIT_COUNTER 0x00000001 /*!< Operate as 1 32-bit counter */
#define SCT_CONFIG_CLKMODE_BUSCLK (0x0 << 1) /*!< Bus clock */
#define SCT_CONFIG_CLKMODE_SCTCLK (0x1 << 1) /*!< SCT clock */
#define SCT_CONFIG_CLKMODE_INCLK (0x2 << 1) /*!< Input clock selected in CLKSEL field */
#define SCT_CONFIG_CLKMODE_INEDGECLK (0x3 << 1) /*!< Input clock edge selected in CLKSEL field */
#define SCT_CONFIG_NORELOAD_U (0x1 << 7) /*!< Prevent match register reload */
#define SCT_CONFIG_NORELOAD_L (0x1 << 7) /*!< Prevent lower match register reload */
#define SCT_CONFIG_NORELOAD_H (0x1 << 8) /*!< Prevent upper match register reload */
#define SCT_CONFIG_AUTOLIMIT_U (0x1 << 17) /*!< Limits counter(unified) based on MATCH0 */
#define SCT_CONFIG_AUTOLIMIT_L (0x1 << 17) /*!< Limits counter(L) based on MATCH0 */
#define SCT_CONFIG_AUTOLIMIT_H (0x1 << 18) /*!< Limits counter(L) based on MATCH0 */
/*
* @brief Macro defines for SCT control register
*/
#define COUNTUP_TO_LIMIT_THEN_CLEAR_TO_ZERO 0 /*!< Direction for low or unified counter */
#define COUNTUP_TO LIMIT_THEN_COUNTDOWN_TO_ZERO 1
#define SCT_CTRL_STOP_L (1 << 1) /*!< Stop low counter */
#define SCT_CTRL_HALT_L (1 << 2) /*!< Halt low counter */
#define SCT_CTRL_CLRCTR_L (1 << 3) /*!< Clear low or unified counter */
#define SCT_CTRL_BIDIR_L(x) (((x) & 0x01) << 4) /*!< Bidirectional bit */
#define SCT_CTRL_PRE_L(x) (((x) & 0xFF) << 5) /*!< Prescale clock for low or unified counter */
#define COUNTUP_TO_LIMIT_THEN_CLEAR_TO_ZERO 0 /*!< Direction for high counter */
#define COUNTUP_TO LIMIT_THEN_COUNTDOWN_TO_ZERO 1
#define SCT_CTRL_STOP_H (1 << 17) /*!< Stop high counter */
#define SCT_CTRL_HALT_H (1 << 18) /*!< Halt high counter */
#define SCT_CTRL_CLRCTR_H (1 << 19) /*!< Clear high counter */
#define SCT_CTRL_BIDIR_H(x) (((x) & 0x01) << 20)
#define SCT_CTRL_PRE_H(x) (((x) & 0xFF) << 21) /*!< Prescale clock for high counter */
/*
* @brief Macro defines for SCT Conflict resolution register
*/
#define SCT_RES_NOCHANGE (0)
#define SCT_RES_SET_OUTPUT (1)
#define SCT_RES_CLEAR_OUTPUT (2)
#define SCT_RES_TOGGLE_OUTPUT (3)
/**
* SCT Match register values enum
*/
typedef enum CHIP_SCT_MATCH_REG {
SCT_MATCH_0 = 0, /*!< SCT Match register 0 */
SCT_MATCH_1 = 1, /*!< SCT Match register 1 */
SCT_MATCH_2 = 2, /*!< SCT Match register 2 */
SCT_MATCH_3 = 3, /*!< SCT Match register 3 */
SCT_MATCH_4 = 4 /*!< SCT Match register 4 */
} CHIP_SCT_MATCH_REG_T;
/**
* SCT Event values enum
*/
typedef enum CHIP_SCT_EVENT {
SCT_EVT_0 = (1 << 0), /*!< Event 0 */
SCT_EVT_1 = (1 << 1), /*!< Event 1 */
SCT_EVT_2 = (1 << 2), /*!< Event 2 */
SCT_EVT_3 = (1 << 3), /*!< Event 3 */
SCT_EVT_4 = (1 << 4) /*!< Event 4 */
} CHIP_SCT_EVENT_T;
/**
* @brief Configures the State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param value : The 32-bit CONFIG register value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_Config(LPC_SCT_T *pSCT, uint32_t value)
{
pSCT->CONFIG = value;
}
/**
* @brief Set or Clear the Control register
* @param pSCT : Pointer to SCT register block
* @param value : SCT Control register value
* @param ena : ENABLE - To set the fields specified by value
* : DISABLE - To clear the field specified by value
* @return Nothing
* Set or clear the control register bits as specified by the \a value
* parameter. If \a ena is set to ENABLE, the mentioned register fields
* will be set. If \a ena is set to DISABLE, the mentioned register
* fields will be cleared
*/
void Chip_SCT_SetClrControl(LPC_SCT_T *pSCT, uint32_t value, FunctionalState ena);
/**
* @brief Set the conflict resolution
* @param pSCT : Pointer to SCT register block
* @param outnum : Output number
* @param value : Output value
* - SCT_RES_NOCHANGE :No change
* - SCT_RES_SET_OUTPUT :Set output
* - SCT_RES_CLEAR_OUTPUT :Clear output
* - SCT_RES_TOGGLE_OUTPUT :Toggle output
* : SCT_RES_NOCHANGE
* : DISABLE - To clear the field specified by value
* @return Nothing
* Set conflict resolution for the output \a outnum
*/
void Chip_SCT_SetConflictResolution(LPC_SCT_T *pSCT, uint8_t outnum, uint8_t value);
/**
* @brief Set unified count value in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param count : The 32-bit count value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetCount(LPC_SCT_T *pSCT, uint32_t count)
{
pSCT->COUNT_U = count;
}
/**
* @brief Set lower count value in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param count : The 16-bit count value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetCountL(LPC_SCT_T *pSCT, uint16_t count)
{
pSCT->COUNT_L = count;
}
/**
* @brief Set higher count value in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param count : The 16-bit count value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetCountH(LPC_SCT_T *pSCT, uint16_t count)
{
pSCT->COUNT_H = count;
}
/**
* @brief Set unified match count value in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param n : Match register value
* @param value : The 32-bit match count value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetMatchCount(LPC_SCT_T *pSCT, CHIP_SCT_MATCH_REG_T n, uint32_t value)
{
pSCT->MATCH[n].U = value;
}
/**
* @brief Set unified match reload count value in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param n : Match register value
* @param value : The 32-bit match count reload value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetMatchReload(LPC_SCT_T *pSCT, CHIP_SCT_MATCH_REG_T n, uint32_t value)
{
pSCT->MATCHREL[n].U = value;
}
/**
* @brief Enable the interrupt for the specified event in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param evt : Event value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_EnableEventInt(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt)
{
pSCT->EVEN = evt | (pSCT->EVEN & ~SCT_EVEN_RESERVED);
}
/**
* @brief Disable the interrupt for the specified event in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param evt : Event value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_DisableEventInt(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt)
{
pSCT->EVEN &= ~(evt | SCT_EVEN_RESERVED);
}
/**
* @brief Clear the specified event flag in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param evt : Event value
* @return Nothing
*/
STATIC INLINE void Chip_SCT_ClearEventFlag(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt)
{
pSCT->EVFLAG = evt | (pSCT->EVFLAG & ~SCT_EVFLAG_RESERVED);
}
/**
* @brief Set control register in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param value : Value (ORed value of SCT_CTRL_* bits)
* @return Nothing
*/
STATIC INLINE void Chip_SCT_SetControl(LPC_SCT_T *pSCT, uint32_t value)
{
pSCT->CTRL_U = value | (pSCT->CTRL_U & ~SCT_CTRL_RESERVED);
}
/**
* @brief Clear control register in State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @param value : Value (ORed value of SCT_CTRL_* bits)
* @return Nothing
*/
STATIC INLINE void Chip_SCT_ClearControl(LPC_SCT_T *pSCT, uint32_t value)
{
pSCT->CTRL_U &= ~(value | SCT_CTRL_RESERVED);
}
/**
* @brief Initializes the State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @return Nothing
*/
void Chip_SCT_Init(LPC_SCT_T *pSCT);
/**
* @brief Deinitializes the State Configurable Timer
* @param pSCT : The base of SCT peripheral on the chip
* @return Nothing
*/
void Chip_SCT_DeInit(LPC_SCT_T *pSCT);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SCT_8XX_H_ */

View File

@ -0,0 +1,85 @@
/*
* @brief LPC8xx State Configurable Timer driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Setup the OUTPUT pin corresponding to the PWM index */
void Chip_SCTPWM_SetOutPin(LPC_SCT_T *pSCT, uint8_t index, uint8_t pin)
{
int ix = (int) index;
pSCT->EV[ix].CTRL = index | (1 << 12);
pSCT->EV[ix].STATE = 1;
pSCT->OUT[pin].SET = 1;
pSCT->OUT[pin].CLR = 1 << ix;
/* Clear the output in-case of conflict */
pSCT->RES = (pSCT->RES & ~(3 << (pin << 1))) | (0x01 << (pin << 1));
/* Set and Clear do not depend on direction */
pSCT->OUTPUTDIRCTRL = (pSCT->OUTPUTDIRCTRL & ~((3 << (pin << 1))|SCT_OUTPUTDIRCTRL_RESERVED));
}
/* Set the PWM frequency */
void Chip_SCTPWM_SetRate(LPC_SCT_T *pSCT, uint32_t freq)
{
uint32_t rate;
rate = Chip_Clock_GetSystemClockRate() / freq;;
/* Stop the SCT before configuration */
Chip_SCTPWM_Stop(pSCT);
/* Set MATCH0 for max limit */
pSCT->REGMODE_U = 0;
Chip_SCT_SetMatchCount(pSCT, SCT_MATCH_0, 0);
Chip_SCT_SetMatchReload(pSCT, SCT_MATCH_0, rate);
pSCT->EV[0].CTRL = 1 << 12;
pSCT->EV[0].STATE = 1;
/* Set SCT Counter to count 32-bits and reset to 0 after reaching MATCH0 */
Chip_SCT_Config(pSCT, SCT_CONFIG_32BIT_COUNTER | SCT_CONFIG_AUTOLIMIT_L);
}

View File

@ -0,0 +1,178 @@
/*
* @brief LPC8xx State Configurable Timer (SCT/PWM) Chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SCT_PWM_8XX_H_
#define __SCT_PWM_8XX_H_
#include "sct_8xx.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup SCT_PWM_8XX CHIP: LPC15XX State Configurable Timer PWM driver
*
* For more information on how to use the driver please visit the FAQ page at
* <a href="http://www.lpcware.com/content/faq/how-use-sct-standard-pwm-using-lpcopen">
* www.lpcware.com</a>
*
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Get number of ticks per PWM cycle
* @param pSCT : The base of SCT peripheral on the chip
* @return Number ot ticks that will be counted per cycle
* @note Return value of this function will be vaild only
* after calling Chip_SCTPWM_SetRate()
*/
STATIC INLINE uint32_t Chip_SCTPWM_GetTicksPerCycle(LPC_SCT_T *pSCT)
{
return pSCT->MATCHREL[0].U;
}
/**
* @brief Converts a percentage to ticks
* @param pSCT : The base of SCT peripheral on the chip
* @param percent : Percentage to convert (0 - 100)
* @return Number ot ticks corresponding to given percentage
* @note Do not use this function when using very low
* pwm rate (like 100Hz or less), on a chip that has
* very high frequency as the calculation might
* cause integer overflow
*/
STATIC INLINE uint32_t Chip_SCTPWM_PercentageToTicks(LPC_SCT_T *pSCT, uint8_t percent)
{
return (Chip_SCTPWM_GetTicksPerCycle(pSCT) * percent) / 100;
}
/**
* @brief Get number of ticks on per PWM cycle
* @param pSCT : The base of SCT peripheral on the chip
* @param index : Index of the PWM 1 to N (see notes)
* @return Number ot ticks for which the output will be ON per cycle
* @note @a index will be 1 to N where N is the "Number of
* match registers available in the SCT - 1" or
* "Number of OUTPUT pins available in the SCT" whichever
* is minimum.
*/
STATIC INLINE uint32_t Chip_SCTPWM_GetDutyCycle(LPC_SCT_T *pSCT, uint8_t index)
{
return pSCT->MATCHREL[index].U;
}
/**
* @brief Get number of ticks on per PWM cycle
* @param pSCT : The base of SCT peripheral on the chip
* @param index : Index of the PWM 1 to N (see notes)
* @param ticks : Number of ticks the output should say ON
* @return None
* @note @a index will be 1 to N where N is the "Number of
* match registers available in the SCT - 1" or
* "Number of OUTPUT pins available in the SCT" whichever
* is minimum. The new duty cycle will be effective only
* after completion of current PWM cycle.
*/
STATIC INLINE void Chip_SCTPWM_SetDutyCycle(LPC_SCT_T *pSCT, uint8_t index, uint32_t ticks)
{
Chip_SCT_SetMatchReload(pSCT, (CHIP_SCT_MATCH_REG_T)index, ticks);
}
/**
* @brief Initialize the SCT/PWM clock and reset
* @param pSCT : The base of SCT peripheral on the chip
* @return None
*/
STATIC INLINE void Chip_SCTPWM_Init(LPC_SCT_T *pSCT)
{
Chip_SCT_Init(pSCT);
}
/**
* @brief Start the SCT PWM
* @param pSCT : The base of SCT peripheral on the chip
* @return None
* @note This function must be called after all the
* configuration is completed. Do not call Chip_SCTPWM_SetRate()
* or Chip_SCTPWM_SetOutPin() after the SCT/PWM is started. Use
* Chip_SCTPWM_Stop() to stop the SCT/PWM before reconfiguring,
* Chip_SCTPWM_SetDutyCycle() can be called when the SCT/PWM is
* running to change the DutyCycle.
*/
STATIC INLINE void Chip_SCTPWM_Start(LPC_SCT_T *pSCT)
{
Chip_SCT_ClearControl(pSCT, SCT_CTRL_HALT_L | SCT_CTRL_HALT_H);
}
/**
* @brief Stop the SCT PWM
* @param pSCT : The base of SCT peripheral on the chip
* @return None
*/
STATIC INLINE void Chip_SCTPWM_Stop(LPC_SCT_T *pSCT)
{
/* Stop SCT */
Chip_SCT_SetControl(pSCT, SCT_CTRL_HALT_L | SCT_CTRL_HALT_H);
/* Clear the counter */
Chip_SCT_SetControl(pSCT, SCT_CTRL_CLRCTR_L | SCT_CTRL_CLRCTR_H);
}
/**
* @brief Sets the frequency of the generated PWM wave
* @param pSCT : The base of SCT peripheral on the chip
* @param freq : Frequency in Hz
* @return None
*/
void Chip_SCTPWM_SetRate(LPC_SCT_T *pSCT, uint32_t freq);
/**
* @brief Setup the OUTPUT pin and associate it with an index
* @param pSCT : The base of the SCT peripheral on the chip
* @param index : Index of PWM 1 to N (see notes)
* @param pin : COUT pin to be associated with the index
* @return None
* @note @a index will be 1 to N where N is the "Number of
* match registers available in the SCT - 1" or
* "Number of OUTPUT pins available in the SCT" whichever
* is minimum.
*/
void Chip_SCTPWM_SetOutPin(LPC_SCT_T *pSCT, uint8_t index, uint8_t pin);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SCT_PWM_8XX_H_ */

View File

@ -0,0 +1,550 @@
/*
* @brief LPC8xx SPI driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
static volatile bool xmitOn;
static volatile bool deasserted;
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
STATIC void SPI_Send_Data_RxIgnore(LPC_SPI_T *pSPI,
SPI_DATA_SETUP_T *pXfSetup)
{
if (pXfSetup->TxCnt == (pXfSetup->Length - 1)) {
Chip_SPI_SendLastFrame_RxIgnore(pSPI, pXfSetup->pTx[pXfSetup->TxCnt], pXfSetup->DataSize);
}
else {
Chip_SPI_SendMidFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt]);
}
pXfSetup->TxCnt++;
}
STATIC void SPI_Send_Data(LPC_SPI_T *pSPI,
SPI_DATA_SETUP_T *pXfSetup)
{
if (pXfSetup->TxCnt == (pXfSetup->Length - 1)) {
Chip_SPI_SendLastFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt], pXfSetup->DataSize);
}
else {
Chip_SPI_SendMidFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt]);
}
pXfSetup->TxCnt++;
}
STATIC void SPI_Send_Dummy(LPC_SPI_T *pSPI,
SPI_DATA_SETUP_T *pXfSetup)
{
if (pXfSetup->RxCnt == (pXfSetup->Length - 1)) {
Chip_SPI_SendLastFrame(pSPI, 0x55, pXfSetup->DataSize);
}
else {
Chip_SPI_SendMidFrame(pSPI, 0x55);
}
}
STATIC void SPI_Receive_Data(LPC_SPI_T *pSPI,
SPI_DATA_SETUP_T *pXfSetup)
{
pXfSetup->pRx[pXfSetup->RxCnt] = Chip_SPI_ReceiveFrame(pSPI);
pXfSetup->RxCnt++;
}
/* Determine SSEL associated with the current data value */
STATIC uint8_t Chip_SPIS_FindSSEL(LPC_SPI_T *pSPI, uint32_t data)
{
int i;
uint8_t ssel = 0;
for (i = 0; i <= 3; i++) {
if ((data & SPI_RXDAT_RXSSELNUM_INACTIVE(i)) == 0) {
/* Signal is active on low */
ssel = (uint8_t) i;
}
}
return ssel;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Calculate the Clock Rate Divider for SPI Peripheral */
uint32_t Chip_SPI_CalClkRateDivider(LPC_SPI_T *pSPI, uint32_t bitRate)
{
uint32_t SPIClk;
uint32_t DivVal = 1;
/* Get SPI clock rate */
SPIClk = Chip_Clock_GetSystemClockRate(); /*The peripheral clock for both SPIs is the system clock*/
DivVal = SPIClk / bitRate;
return DivVal;
}
/* Configure SPI Delay parameters */
void Chip_SPI_DelayConfig(LPC_SPI_T *pSPI, SPI_DELAY_CONFIG_T *pConfig)
{
uint32_t delayValue = SPI_DLY_PRE_DELAY(pConfig->PreDelay) |
SPI_DLY_POST_DELAY(pConfig->PostDelay) |
SPI_DLY_FRAME_DELAY(pConfig->FrameDelay);
if (pConfig->TransferDelay) {
delayValue |= SPI_DLY_TRANSFER_DELAY(pConfig->TransferDelay - 1);
}
pSPI->DLY = delayValue;
}
/* Disable/Enable Interrupt */
void Chip_SPI_Int_Cmd(LPC_SPI_T *pSPI, uint32_t IntMask, FunctionalState NewState)
{
if (NewState == ENABLE) {
pSPI->INTENSET = IntMask;
}
else {
pSPI->INTENCLR = IntMask;
}
}
/*Send and Receive SPI Data */
uint32_t Chip_SPI_RWFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
{
uint32_t Status;
/* Clear status */
Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD);
Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, SPI_TXCTL_ASSERT_SSEL | SPI_TXCTL_EOF);
pXfSetup->TxCnt = pXfSetup->RxCnt = 0;
while ((pXfSetup->TxCnt < pXfSetup->Length) ||
(pXfSetup->RxCnt < pXfSetup->Length)) {
Status = Chip_SPI_GetStatus(pSPI);
/* In case of TxReady */
if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) {
SPI_Send_Data(pSPI, pXfSetup);
}
/*In case of Rx ready */
if ((Status & SPI_STAT_RXRDY) && (pXfSetup->RxCnt < pXfSetup->Length)) {
SPI_Receive_Data(pSPI, pXfSetup);
}
}
/* Check error */
if (Chip_SPI_GetStatus(pSPI) & (SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR)) {
return 0;
}
return pXfSetup->TxCnt;
}
uint32_t Chip_SPI_WriteFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
{
/* Clear status */
Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD);
Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, SPI_TXCTL_ASSERT_SSEL | SPI_TXCTL_EOF | SPI_TXCTL_RXIGNORE);
pXfSetup->TxCnt = pXfSetup->RxCnt = 0;
while (pXfSetup->TxCnt < pXfSetup->Length) {
/* Wait for TxReady */
while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY)) {}
SPI_Send_Data_RxIgnore(pSPI, pXfSetup);
}
/* Make sure the last frame sent completely*/
while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSD)) {}
Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_SSD);
/* Check overrun error */
if (Chip_SPI_GetStatus(pSPI) & SPI_STAT_CLR_TXUR) {
return 0;
}
return pXfSetup->TxCnt;
}
uint32_t Chip_SPI_ReadFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
{
/* Clear status */
Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD);
Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, SPI_TXCTL_ASSERT_SSEL | SPI_TXCTL_EOF);
pXfSetup->TxCnt = pXfSetup->RxCnt = 0;
while (pXfSetup->RxCnt < pXfSetup->Length) {
/* Wait for TxReady */
while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY)) {}
SPI_Send_Dummy(pSPI, pXfSetup);
/* Wait for receive data */
while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_RXRDY)) {}
SPI_Receive_Data(pSPI, pXfSetup);
}
/* Check overrun error */
if (Chip_SPI_GetStatus(pSPI) & (SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR)) {
return 0;
}
return pXfSetup->RxCnt;
}
/* SPI Interrupt Read/Write with 8-bit frame width */
Status Chip_SPI_Int_RWFrames(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
{
uint32_t Status;
Status = Chip_SPI_GetStatus(pSPI);
/* Check error in INTSTAT register */
if (Status & (SPI_STAT_RXOV | SPI_STAT_TXUR)) {
return ERROR;
}
if (pXfSetup->TxCnt == 0) {
Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, SPI_TXCTL_ASSERT_SSEL | SPI_TXCTL_EOF);
}
if (pXfSetup->pRx == NULL) {
if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) {
SPI_Send_Data_RxIgnore(pSPI, pXfSetup);
}
}
else {
/* check if Tx ready */
if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) {
SPI_Send_Data(pSPI, pXfSetup);
}
/* check if RX FIFO contains data */
if ((Status & SPI_STAT_RXRDY) && (pXfSetup->RxCnt < pXfSetup->Length)) {
SPI_Receive_Data(pSPI, pXfSetup);
}
}
return SUCCESS;
}
/* Get SPI master bit rate */
uint32_t Chip_SPIM_GetClockRate(LPC_SPI_T *pSPI)
{
return Chip_Clock_GetSystemClockRate() / ((pSPI->DIV & ~SPI_DIV_RESERVED) + 1);
}
/* Set SPI master bit rate */
uint32_t Chip_SPIM_SetClockRate(LPC_SPI_T *pSPI, uint32_t rate)
{
uint32_t baseClock, div;
/* Get peripheral base clock rate */
baseClock = Chip_Clock_GetSystemClockRate();
/* Compute divider */
div = baseClock / rate;
/* Limit values */
if (div == 0) {
div = 1;
}
else if (div > 0x10000) {
div = 0x10000;
}
pSPI->DIV = div - 1;
return Chip_SPIM_GetClockRate(pSPI);
}
/* Configure SPI Delay parameters */
void Chip_SPIM_DelayConfig(LPC_SPI_T *pSPI, SPIM_DELAY_CONFIG_T *pConfig)
{
pSPI->DLY = (SPI_DLY_PRE_DELAY(pConfig->PreDelay) |
SPI_DLY_POST_DELAY(pConfig->PostDelay) |
SPI_DLY_FRAME_DELAY(pConfig->FrameDelay) |
SPI_DLY_TRANSFER_DELAY(pConfig->TransferDelay - 1));
}
/* Assert a SPI select */
void Chip_SPIM_AssertSSEL(LPC_SPI_T *pSPI, uint8_t sselNum)
{
uint32_t reg;
reg = pSPI->TXCTRL & SPI_TXDATCTL_CTRLMASK;
/* Assert a SSEL line by driving it low */
reg &= ~SPI_TXDATCTL_DEASSERTNUM_SSEL(sselNum);
pSPI->TXCTRL = reg;
}
/* Deassert a SPI select */
void Chip_SPIM_DeAssertSSEL(LPC_SPI_T *pSPI, uint8_t sselNum)
{
uint32_t reg;
reg = pSPI->TXCTRL & SPI_TXDATCTL_CTRLMASK;
pSPI->TXCTRL = reg | SPI_TXDATCTL_DEASSERTNUM_SSEL(sselNum);
}
/* SPI master transfer state change handler */
void Chip_SPIM_XferHandler(LPC_SPI_T *pSPI, SPIM_XFER_T *xfer)
{
uint32_t data;
uint8_t flen;
/* Get length of a receive value */
flen = ((pSPI->TXCTRL & ~SPI_TXCTRL_RESERVED) >> 24) & 0xF;
/* Master asserts slave */
if ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSA) != 0) {
Chip_SPI_ClearStatus(pSPI, SPI_STAT_SSA);
/* SSEL assertion callback */
xfer->pCB->masterXferCSAssert(xfer);
}
/* Slave de-assertion */
if ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSD) != 0) {
Chip_SPI_ClearStatus(pSPI, SPI_STAT_SSD);
/* If transmitter disabled and deassert happens, the transfer is done */
if (xmitOn == false) {
xfer->pCB->mMasterXferDone(xfer);
}
}
/* Transmit data? */
while (((Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY) != 0) && (xmitOn == true)) {
if ((xfer->txCount == 1) && (xfer->terminate)) {
/* Transfer is done, this will be last data */
Chip_SPIM_ForceEndOfTransfer(pSPI);
xmitOn = false;
}
else if (xfer->txCount == 0) {
/* Request a new buffer first */
xfer->pCB->masterXferSend(xfer);
}
if (xfer->txCount > 0) {
/* Send 0 if ignoring transmit */
if (xfer->pTXData8 == NULL) {
data = 0;
}
else {
/* Copy buffer to data */
if (flen > 8) {
data = (uint32_t) *xfer->pTXData16;
xfer->pTXData16++;
}
else {
data = (uint32_t) *xfer->pTXData8;
xfer->pTXData8++;
}
xfer->dataTXferred++;
}
Chip_SPI_WriteTXData(pSPI, data);
xfer->txCount--;
}
}
/* Data received? */
while ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_RXRDY) != 0) {
/* Get raw data and status */
data = Chip_SPI_ReadRawRXFifo(pSPI);
/* Only copy data when not ignoring receive */
if (xfer->pRXData8 != NULL) {
/* Enough size in current buffers? */
if (xfer->rxCount == 0) {
/* Request a new buffer first */
xfer->pCB->masterXferRecv(xfer);
}
/* Copy data to buffer */
if (xfer->rxCount > 0) {
if (flen > 8) {
*xfer->pRXData16 = (uint16_t) (data & 0xFFFF);
xfer->pRXData16++;
}
else {
*xfer->pRXData8 = (uint8_t) (data & 0xFF);
xfer->pRXData8++;
}
xfer->dataRXferred++;
xfer->rxCount--;
}
}
}
}
/* Start non-blocking SPI master transfer */
void Chip_SPIM_Xfer(LPC_SPI_T *pSPI, SPIM_XFER_T *xfer)
{
/* Setup SPI master select, data length, EOT/EOF timing, and RX data ignore */
pSPI->TXCTRL = xfer->options | SPI_TXDATCTL_DEASSERT_ALL;
Chip_SPIM_AssertSSEL(pSPI, xfer->sselNum);
/* Clear initial transfer states */
xfer->dataRXferred = xfer->dataTXferred = 0;
/* Call main handler to start transfer */
xmitOn = true;
Chip_SPIM_XferHandler(pSPI, xfer);
}
/* Perform blocking SPI master transfer */
void Chip_SPIM_XferBlocking(LPC_SPI_T *pSPI, SPIM_XFER_T *xfer)
{
/* Start trasnfer */
Chip_SPIM_Xfer(pSPI, xfer);
/* Wait for termination */
while (xmitOn == true) {
Chip_SPIM_XferHandler(pSPI, xfer);
}
}
/* SPI slave transfer state change handler */
uint32_t Chip_SPIS_XferHandler(LPC_SPI_T *pSPI, SPIS_XFER_T *xfer)
{
uint32_t staterr, data;
uint8_t flen;
/* Get length of a receive value */
flen = ((pSPI->TXCTRL & ~SPI_TXCTRL_RESERVED) >> 24) & 0xF;
/* Get errors for later, we'll continue even if errors occur, but we notify
caller on return */
staterr = Chip_SPI_GetStatus(pSPI) & (SPI_STAT_RXOV | SPI_STAT_TXUR);
if (staterr != 0) {
Chip_SPI_ClearStatus(pSPI, staterr);
}
/* Slave assertion */
if ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSA) != 0) {
Chip_SPI_ClearStatus(pSPI, SPI_STAT_SSA);
/* Determine SPI select. Read the data FIFO to get the slave number. Data
should not be in the receive FIFO yet, only the statuses */
xfer->sselNum = Chip_SPIS_FindSSEL(pSPI, Chip_SPI_ReadRawRXFifo(pSPI));
/* SSEL assertion callback */
xfer->pCB->slaveXferCSAssert(xfer);
}
/* Slave de-assertion */
if ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSD) != 0) {
Chip_SPI_ClearStatus(pSPI, SPI_STAT_SSD);
deasserted = true;
xfer->pCB->slaveXferCSDeAssert(xfer);
}
/* Transmit data? */
while ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY) != 0) {
if (xfer->txCount == 0) {
/* Request a new buffer first */
xfer->pCB->slaveXferSend(xfer);
}
/* Send 0 on empty buffer or count */
if ((xfer->txCount == 0) || (xfer->pTXData8 == NULL)) {
data = 0;
}
else {
/* Copy buffer to data */
if (flen > 8) {
data = (uint32_t) *xfer->pTXData16;
xfer->pTXData16++;
}
else {
data = (uint32_t) *xfer->pTXData8;
xfer->pTXData8++;
}
xfer->dataTXferred++;
xfer->txCount--;
}
Chip_SPI_WriteTXData(pSPI, data);
}
/* Data received? */
while ((Chip_SPI_GetStatus(pSPI) & SPI_STAT_RXRDY) != 0) {
/* Get raw data and status */
data = Chip_SPI_ReadRawRXFifo(pSPI);
/* Only copy data when not ignoring receive */
if (xfer->pRXData8 != NULL) {
/* Enough size in current buffers? */
if (xfer->rxCount == 0) {
/* Request a new buffer first */
xfer->pCB->slaveXferRecv(xfer);
}
/* Copy data to buffer */
if (flen > 8) {
*xfer->pRXData16 = (uint16_t) (data & 0xFFFF);
xfer->pRXData16++;
}
else {
*xfer->pRXData8 = (uint8_t) (data & 0xFF);
xfer->pRXData8++;
}
xfer->dataRXferred++;
xfer->rxCount--;
}
}
return staterr;
}
/* SPI slave transfer blocking function */
uint32_t Chip_SPIS_XferBlocking(LPC_SPI_T *pSPI, SPIS_XFER_T *xfer)
{
uint32_t status = 0;
/* Wait forever until deassertion event */
deasserted = false;
while ((!deasserted) && (status == 0)) {
status = Chip_SPIS_XferHandler(pSPI, xfer);
}
return status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,177 @@
/*
* @brief Common ring buffer support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "ring_buffer.h"
int32_t RingBuf_Init(ring_buffer_t* pRB, uint8_t* buffer, uint32_t size )
{
pRB->pBuf = (uint8_t*)buffer;
pRB->size = size;
pRB->rNdx = 0;
pRB->wNdx = 0;
pRB->cnt = 0;
return 0;
}
int32_t RingBuf_Deinit(ring_buffer_t* pRB )
{
pRB = pRB;;
return 0;
}
int32_t RingBuf_GetFreeBytes(ring_buffer_t* pRB )
{
return pRB->size - pRB->cnt;
}
int32_t RingBuf_GetUsedBytes(ring_buffer_t* pRB)
{
return pRB->cnt;
}
int32_t RingBuf_Write(ring_buffer_t* pRB, const uint8_t* data, uint32_t dataBytes)
{
uint32_t writeToEnd, bytesToCopy;
INIT_CRITICAL();
ENTER_CRITICAL();
/* Calculate the maximum amount we can copy */
writeToEnd = pRB->size - pRB->wNdx;
bytesToCopy = MIN(dataBytes, pRB->size - pRB->cnt);
if (bytesToCopy != 0)
{
/* Copy as much as we can until we fall off the end of the buffer */
memcpy(&pRB->pBuf[pRB->wNdx], data, MIN(bytesToCopy, writeToEnd));
/* Check if we have more to copy to the front of the buffer */
if (writeToEnd < bytesToCopy)
{
memcpy(pRB->pBuf, data + writeToEnd, bytesToCopy - writeToEnd);
}
/* Update the wNdx */
pRB->wNdx = (pRB->wNdx + bytesToCopy) % pRB->size;
pRB->cnt += dataBytes;
}
LEAVE_CRITICAL();
return bytesToCopy;
}
int32_t RingBuf_Write1Byte(ring_buffer_t* pRB, const uint8_t *pcData)
{
uint32_t ret = 0;
INIT_CRITICAL();
ENTER_CRITICAL();
if (pRB->cnt < pRB->size)
{
pRB->pBuf[pRB->wNdx] = pcData[0];
pRB->wNdx = (pRB->wNdx + 1) % pRB->size;
pRB->cnt++;
ret = 1;
}
LEAVE_CRITICAL();
return ret;
}
int32_t _prvRingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes, uint32_t isToFree)
{
uint32_t readToEnd, bytesToCopy;
INIT_CRITICAL();
ENTER_CRITICAL();
readToEnd = pRB->size - pRB->rNdx;
bytesToCopy = MIN(dataBytes, pRB->cnt);
if (bytesToCopy != 0)
{
memcpy(data, &pRB->pBuf[pRB->rNdx], MIN(bytesToCopy, readToEnd));
if (readToEnd < bytesToCopy)
memcpy(data + readToEnd, &pRB->pBuf[0], bytesToCopy - readToEnd);
if (isToFree)
{
pRB->rNdx = (pRB->rNdx + bytesToCopy) % pRB->size;
pRB->cnt -= bytesToCopy;
}
}
LEAVE_CRITICAL();
return bytesToCopy;
}
int32_t RingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
{
return _prvRingBuf_Read(pRB, data, dataBytes, 1);
}
int32_t RingBuf_Copy(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
{
return _prvRingBuf_Read(pRB, data, dataBytes, 0);
}
int32_t RingBuf_Read1Byte(ring_buffer_t* pRB, uint8_t *pData)
{
uint32_t ret = 0;
INIT_CRITICAL();
ENTER_CRITICAL();
if (pRB->cnt != 0)
{
pData[0] = pRB->pBuf[pRB->rNdx];
pRB->rNdx = (pRB->rNdx + 1) % pRB->size;
pRB->cnt--;
ret = 1;
}
LEAVE_CRITICAL();
return ret;
}
int32_t RingBuf_Peek(ring_buffer_t* pRB, uint8_t **ppData)
{
uint32_t readToEnd = pRB->size - pRB->rNdx;
uint32_t contiguousBytes;
*ppData = &(pRB->pBuf[pRB->rNdx]);
contiguousBytes = MIN(readToEnd, (readToEnd + pRB->wNdx) % pRB->size);
return contiguousBytes;
}
int32_t RingBuf_Free(ring_buffer_t* pRB, uint32_t bytesToFree)
{
INIT_CRITICAL();
ENTER_CRITICAL();
pRB->rNdx = (pRB->rNdx + bytesToFree) % pRB->size;
pRB->cnt -= bytesToFree;
LEAVE_CRITICAL();
return bytesToFree;
}

View File

@ -0,0 +1,157 @@
/*
* @brief Common ring buffer support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __RING_BUFFER_H_
#define __RING_BUFFER_H_
#include <stdint.h>
#include <string.h>
#define RINGBUF_IRQ_SAFE
#ifdef RINGBUF_IRQ_SAFE
#include <cmsis.h>
#define INIT_CRITICAL() uint32_t priMask = __get_PRIMASK()
#define ENTER_CRITICAL() __set_PRIMASK(1)
#define LEAVE_CRITICAL() __set_PRIMASK(priMask)
#else
#define INIT_CRITICAL()
#define ENTER_CRITICAL()
#define LEAVE_CRITICAL()
#endif
typedef struct
{
uint8_t *pBuf;
uint32_t size;
uint32_t cnt;
uint32_t rNdx;
uint32_t wNdx;
} ring_buffer_t, RINGBUFF_T;
#ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif /* ifndef MIN */
/**
* @brief Create and initialize a ring buffer
* @param pRB : pointer to ring buffer instance
* @param pBuffer: pointer to the buffer for ring buffer data
* @param size: The size of buffer pointed by pBuffer
* @return >=0:Success ; <0:Failed
*/
int32_t RingBuf_Init(ring_buffer_t *pRB, uint8_t *pBuffer, uint32_t size);
/**
* @brief Write new data to buffer
* @param pRB : pointer to the ring buffer instance
* @param pcData: point to data array that will be written to ring buffer
* @param dataBytes: bytes to write
* @return >=0:Bytes written ; <0:Failed
* @remark This function updates the ring buffer
*/
int32_t RingBuf_Write(ring_buffer_t* pRB, const uint8_t *pcData, uint32_t dataBytes);
/**
* @brief Write 1 new byte data to buffer
* @param pRB : pointer to the ring buffer instance
* @param pcData: point to data byte that will be written to ring buffer
* @return 1:success; otherwise failed
* @remark This function updates the ring buffer. Optimized for byte-by-byte write
*/
int32_t RingBuf_Write1Byte(ring_buffer_t* pRB, const uint8_t *pcData);
/**
* @brief Read (copy and remove) data from ring buffer
* @param pRB : pointer to the ring buffer instance
* @param pData : pointer to data array that receives read data
* @param dataBytes: bytes to copy
* @return >=0:Bytes read ; <0:Failed
* @remark This function updates the ring buffer.
*/
int32_t RingBuf_Read(ring_buffer_t* pRB, uint8_t *pData, uint32_t dataBytes);
/**
* @brief Read (copy and remove) 1 oldest byte data from buffer
* @param pRB : pointer to the ring buffer instance
* @param pData: point to data byte that will receive the oldest byte
* @return 1:success ; otherwise failed
* @remark This function updates the ring buffer. Optimized for byte-by-byte read
*/
int32_t RingBuf_Read1Byte(ring_buffer_t* pRB, uint8_t *pData);
/**
* @brief Copy but does NOT remove data from ring buffer
* @param pRB : pointer to the ring buffer instance
* @param pData : pointer to data array that receives read data
* @param dataBytes: bytes to read
* @return >=0:Read bytes ; <0:Failed
*/
int32_t RingBuf_Copy(ring_buffer_t* pRB, uint8_t *pData, uint32_t dataBytes);
/**
* @brief Get data pointer to oldest byte in ring buffer, and contigous byte count
* @param pRB : pointer to the ring buffer instance
* @param ppData : pointer to pointer variable that will be updated to point to oldest byte
* @param contiguous_bytes: Congigous bytes until roll back
* @return >=0:Contiuous bytes until roll back or whole data (if roll back won't happen) ; <0:Failed
* @remak Use this function if performance is critical since it does NOT copy data
* Use RingBuf_Free() to free (remove) data after use
*/
int32_t RingBuf_Peek(ring_buffer_t* pRB, uint8_t **ppData);
/**
* @brief Free (remove) data from ring buffer
* @param pRB : pointer to the ring buffer instance
* @param bytesToFree : Bytes to free (remove)
* @remak Use this function to free data after data get from RingBuf_Peek() is used
*/
int32_t RingBuf_Free(ring_buffer_t* pRB, uint32_t bytesToFree);
/**
* @brief Get free bytes of ring buffer
* @param pRB : pointer to the ring buffer instance
* @return >=0:Free bytes ; <0:Failed
*/
int32_t RingBuf_GetFreeBytes(ring_buffer_t* pRB);
/**
* @brief Get free bytes of ring buffer
* @param pRB : pointer to the ring buffer instance
* @return >=0:Used bytes ; <0:Failed
*/
int32_t RingBuf_GetUsedBytes(ring_buffer_t* pRB);
/**
* @}
*/
#endif /* __RING_BUFFER_H_ */

View File

@ -0,0 +1,232 @@
/*
* @brief LPC8xx UART driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#include "uart_8xx.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/* Return UART clock ID from the UART register address */
static CHIP_SYSCTL_CLOCK_T getUARTClockID(LPC_USART_T *pUART)
{
if (pUART == LPC_USART0) {
return SYSCTL_CLOCK_UART0;
}
else if (pUART == LPC_USART1) {
return SYSCTL_CLOCK_UART1;
}
return SYSCTL_CLOCK_UART2;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the UART peripheral */
void Chip_UART_Init(LPC_USART_T *pUART)
{
/* Enable USART clock */
Chip_Clock_EnablePeriphClock(getUARTClockID(pUART));
/* UART reset */
if (pUART == LPC_USART0) {
/* Peripheral reset control to USART0 */
Chip_SYSCTL_PeriphReset(RESET_USART0);
}
else if (pUART == LPC_USART1) {
/* Peripheral reset control to USART1 */
Chip_SYSCTL_PeriphReset(RESET_USART1);
}
else {
/* Peripheral reset control to USART2 */
Chip_SYSCTL_PeriphReset(RESET_USART2);
}
}
/* Initialize the UART peripheral */
void Chip_UART_DeInit(LPC_USART_T *pUART)
{
/* Disable USART clock */
Chip_Clock_DisablePeriphClock(getUARTClockID(pUART));
}
/* Transmit a byte array through the UART peripheral (non-blocking) */
int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes)
{
int sent = 0;
uint8_t *p8 = (uint8_t *) data;
/* Send until the transmit FIFO is full or out of bytes */
while ((sent < numBytes) &&
((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0)) {
Chip_UART_SendByte(pUART, *p8);
p8++;
sent++;
}
return sent;
}
/* Transmit a byte array through the UART peripheral (blocking) */
int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
{
int pass, sent = 0;
uint8_t *p8 = (uint8_t *) data;
while (numBytes > 0) {
pass = Chip_UART_Send(pUART, p8, numBytes);
numBytes -= pass;
sent += pass;
p8 += pass;
}
return sent;
}
/* Read data through the UART peripheral (non-blocking) */
int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes)
{
int readBytes = 0;
uint8_t *p8 = (uint8_t *) data;
/* Send until the transmit FIFO is full or out of bytes */
while ((readBytes < numBytes) &&
((Chip_UART_GetStatus(pUART) & UART_STAT_RXRDY) != 0)) {
*p8 = Chip_UART_ReadByte(pUART);
p8++;
readBytes++;
}
return readBytes;
}
/* Read data through the UART peripheral (blocking) */
int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes)
{
int pass, readBytes = 0;
uint8_t *p8 = (uint8_t *) data;
while (numBytes > 0) {
pass = Chip_UART_Read(pUART, p8, numBytes);
numBytes -= pass;
readBytes += pass;
p8 += pass;
}
return readBytes;
}
/* Set baud rate for UART */
void Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate)
{
uint32_t baudRateGenerator;
baudRateGenerator = Chip_Clock_GetUSARTNBaseClockRate() / (16 * baudrate);
pUART->BRG = baudRateGenerator - 1; /* baud rate */
}
/* UART receive-only interrupt handler for ring buffers */
void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
{
/* New data will be ignored if data not popped in time */
while ((Chip_UART_GetStatus(pUART) & UART_STAT_RXRDY) != 0) {
uint8_t ch = Chip_UART_ReadByte(pUART);
RingBuf_Write(pRB, &ch, 1);
}
}
/* UART transmit-only interrupt handler for ring buffers */
void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
{
uint8_t ch;
/* Fill FIFO until full or until TX ring buffer is empty */
while (((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0) &&
RingBuf_Read(pRB, &ch, 1)) {
Chip_UART_SendByte(pUART, ch);
}
}
/* Populate a transmit ring buffer and start UART transmit */
uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int count)
{
uint32_t ret;
uint8_t *p8 = (uint8_t *) data;
/* Don't let UART transmit ring buffer change in the UART IRQ handler */
Chip_UART_IntDisable(pUART, UART_INTEN_TXRDY);
/* Move as much data as possible into transmit ring buffer */
ret = RingBuf_Write(pRB, p8, count);
Chip_UART_TXIntHandlerRB(pUART, pRB);
/* Add additional data to transmit ring buffer if possible */
ret += RingBuf_Write(pRB, (p8 + ret), (count - ret));
/* Enable UART transmit interrupt */
Chip_UART_IntEnable(pUART, UART_INTEN_TXRDY);
return ret;
}
/* Copy data from a receive ring buffer */
int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes)
{
(void) pUART;
return RingBuf_Read(pRB, (uint8_t *) data, bytes);
}
/* UART receive/transmit interrupt handler for ring buffers */
void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
{
/* Handle transmit interrupt if enabled */
if ((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0) {
Chip_UART_TXIntHandlerRB(pUART, pTXRB);
/* Disable transmit interrupt if the ring buffer is empty */
if (RingBuf_GetFreeBytes(pTXRB) == 0) {
Chip_UART_IntDisable(pUART, UART_INTEN_TXRDY);
}
}
/* Handle receive interrupt */
Chip_UART_RXIntHandlerRB(pUART, pRXRB);
}

View File

@ -0,0 +1,491 @@
/*
* @brief LPC8xx UART driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __UART_8XX_H_
#define __UART_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "ring_buffer.h"
/** @defgroup UART_8XX CHIP: LPC8xx UART Driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief UART register block structure
*/
typedef struct {
__IO uint32_t CFG; /*!< Configuration register */
__IO uint32_t CTRL; /*!< Control register */
__IO uint32_t STAT; /*!< Status register */
__IO uint32_t INTENSET; /*!< Interrupt Enable read and set register */
__O uint32_t INTENCLR; /*!< Interrupt Enable clear register */
__I uint32_t RXDATA; /*!< Receive Data register */
__I uint32_t RXDATA_STAT; /*!< Receive Data with status register */
__IO uint32_t TXDATA; /*!< Transmit data register */
__IO uint32_t BRG; /*!< Baud Rate Generator register */
__IO uint32_t INTSTAT; /*!< Interrupt status register */
__IO uint32_t OSR; /*!< Oversampling Selection regiser */
__IO uint32_t ADDR; /*!< Address register for automatic address matching */
} LPC_USART_T;
/**
* @brief UART CFG register definitions
*/
#define UART_CFG_ENABLE (0x01 << 0)
#define UART_CFG_DATALEN_7 (0x00 << 2) /*!< UART 7 bit length mode */
#define UART_CFG_DATALEN_8 (0x01 << 2) /*!< UART 8 bit length mode */
#define UART_CFG_DATALEN_9 (0x02 << 2) /*!< UART 9 bit length mode */
#define UART_CFG_PARITY_NONE (0x00 << 4) /*!< No parity */
#define UART_CFG_PARITY_EVEN (0x02 << 4) /*!< Even parity */
#define UART_CFG_PARITY_ODD (0x03 << 4) /*!< Odd parity */
#define UART_CFG_STOPLEN_1 (0x00 << 6) /*!< UART One Stop Bit Select */
#define UART_CFG_STOPLEN_2 (0x01 << 6) /*!< UART Two Stop Bits Select */
#define UART_CFG_CTSEN (0x01 << 9) /*!< CTS enable bit */
#define UART_CFG_SYNCEN (0x01 << 11) /*!< Synchronous mode enable bit */
#define UART_CFG_CLKPOL (0x01 << 12) /*!< Un_RXD rising edge sample enable bit */
#define UART_CFG_SYNCMST (0x01 << 14) /*!< Select master mode (synchronous mode) enable bit */
#define UART_CFG_LOOP (0x01 << 15) /*!< Loopback mode enable bit */
#ifdef CHIP_LPC82X /* LPC82X specific bits */
#define UART_CFG_OETA (0x01 << 18) /*!< Output Enable Turnaround time for RS485 */
#define UART_CFG_AUTOADDR (0x01 << 19) /*!< Automatic address matching enable */
#define UART_CFG_OESEL (0x01 << 20) /*!< Output enable select */
#define UART_CFG_OEPOL (0x01 << 21) /*!< Output enable polarity */
#define UART_CFG_RXPOL (0x01 << 22) /*!< Receive data polarity */
#define UART_CFG_TXPOL (0x01 << 22) /*!< Transmit data polarity */
#define UART_CFG_RESERVED ((1<<1)|(1<<7)|(1<<8)|(1<<10)|(1<<13)|(3 << 16)|(0xffu<<24))
#else
#define UART_CFG_RESERVED ((1<<1)|(1<<7)|(1<<8)|(1<<10)|(1<<13)|(0xffffu<<16))
#endif
/**
* @brief UART CTRL register definitions
*/
#define UART_CTRL_TXBRKEN (0x01 << 1) /*!< Continuous break enable bit */
#define UART_CTRL_ADDRDET (0x01 << 2) /*!< Address detect mode enable bit */
#define UART_CTRL_TXDIS (0x01 << 6) /*!< Transmit disable bit */
#define UART_CTRL_CC (0x01 << 8) /*!< Continuous Clock mode enable bit */
#define UART_CTRL_CLRCC (0x01 << 9) /*!< Clear Continuous Clock bit */
#ifdef CHIP_LPC82X
#define UART_CTRL_AUTOBAUD (1 << 16) /*!< Enable UART Autobaud */
#define UART_CTRL_RESERVED (0xFFFEFCB9U)
#else
#define UART_CTRL_RESERVED (1|(7<<3)|(1<<7)|0xfffffc00u)
#endif
/**
* @brief UART STAT register definitions
*/
#define UART_STAT_RXRDY (0x01 << 0) /*!< Receiver ready */
#define UART_STAT_RXIDLE (0x01 << 1) /*!< Receiver idle */
#define UART_STAT_TXRDY (0x01 << 2) /*!< Transmitter ready for data */
#define UART_STAT_TXIDLE (0x01 << 3) /*!< Transmitter idle */
#define UART_STAT_CTS (0x01 << 4) /*!< Status of CTS signal */
#define UART_STAT_DELTACTS (0x01 << 5) /*!< Change in CTS state */
#define UART_STAT_TXDISINT (0x01 << 6) /*!< Transmitter disabled */
#define UART_STAT_OVERRUNINT (0x01 << 8) /*!< Overrun Error interrupt flag. */
#define UART_STAT_RXBRK (0x01 << 10) /*!< Received break */
#define UART_STAT_DELTARXBRK (0x01 << 11) /*!< Change in receive break detection */
#define UART_STAT_START (0x01 << 12) /*!< Start detected */
#define UART_STAT_FRM_ERRINT (0x01 << 13) /*!< Framing Error interrupt flag */
#define UART_STAT_PAR_ERRINT (0x01 << 14) /*!< Parity Error interrupt flag */
#define UART_STAT_RXNOISEINT (0x01 << 15) /*!< Received Noise interrupt flag */
#ifdef CHIP_LPC82X
#define UART_STAT_ABERR (0x01 << 16) /*!< Auto baud error */
#define UART_STAT_RESERVED ((1<<7)|(1<<9)|(0xFFFEU<<16))
#else
#define UART_STAT_RESERVED ((1<<7)|(1<<9)|(0xffffu<<16))
#endif
/**
* @brief UART INTENSET/INTENCLR register definitions
*/
#define UART_INTEN_RXRDY (0x01 << 0) /*!< Receive Ready interrupt */
#define UART_INTEN_TXRDY (0x01 << 2) /*!< Transmit Ready interrupt */
#define UART_INTEN_DELTACTS (0x01 << 5) /*!< Change in CTS state interrupt */
#define UART_INTEN_TXDIS (0x01 << 6) /*!< Transmitter disable interrupt */
#define UART_INTEN_OVERRUN (0x01 << 8) /*!< Overrun error interrupt */
#define UART_INTEN_DELTARXBRK (0x01 << 11) /*!< Change in receiver break detection interrupt */
#define UART_INTEN_START (0x01 << 12) /*!< Start detect interrupt */
#define UART_INTEN_FRAMERR (0x01 << 13) /*!< Frame error interrupt */
#define UART_INTEN_PARITYERR (0x01 << 14) /*!< Parity error interrupt */
#define UART_INTEN_RXNOISE (0x01 << 15) /*!< Received noise interrupt */
#ifdef CHIP_LPC82X
#define UART_INTEN_TXIDLE (0x01 << 3) /*!< TX Idle enable/clear */
#define UART_INTEN_ABERR (0x01 << 16) /*!< Auto baud error */
#define UART_INTEN_RESERVED ((1<<1)|(1<<4)|(1<<7)|(3<<9)|(0xfffeu<<16))
#define UART_INTSTAT_RESERVED ((1<<1)|(1<<4)|(1<<7)|(3<<9)|(0xfffeu<<16))
#else
#define UART_INTEN_RESERVED ((1<<1)|(3<<3)|(1<<7)|(3<<9)|(0xffffu<<16))
#define UART_INTSTAT_RESERVED ((1<<1)|(3<<3)|(1<<7)|(3<<9)|(0xffffu<<16))
#endif
/**
* @brief Enable the UART
* @param pUART : Pointer to selected UARTx peripheral
* @return Nothing
*/
STATIC INLINE void Chip_UART_Enable(LPC_USART_T *pUART)
{
pUART->CFG = UART_CFG_ENABLE | (pUART->CFG & ~UART_CFG_RESERVED);
}
/**
* @brief Disable the UART
* @param pUART : Pointer to selected UARTx peripheral
* @return Nothing
*/
STATIC INLINE void Chip_UART_Disable(LPC_USART_T *pUART)
{
pUART->CFG &= ~(UART_CFG_RESERVED | UART_CFG_ENABLE);
}
STATIC INLINE void Chip_UART_LoopbackConfig(LPC_USART_T *pUART, uint32_t isEn)
{
if (isEn)
pUART->CFG |= UART_CFG_LOOP;
else
pUART->CFG &= ~UART_CFG_LOOP;
}
/**
* @brief Enable transmission on UART TxD pin
* @param pUART : Pointer to selected pUART peripheral
* @return Nothing
*/
STATIC INLINE void Chip_UART_TXEnable(LPC_USART_T *pUART)
{
pUART->CTRL &= ~(UART_CTRL_RESERVED | UART_CTRL_TXDIS);
}
/**
* @brief Disable transmission on UART TxD pin
* @param pUART : Pointer to selected pUART peripheral
* @return Nothing
*/
STATIC INLINE void Chip_UART_TXDisable(LPC_USART_T *pUART)
{
pUART->CTRL = UART_CTRL_TXDIS | (pUART->CTRL & ~UART_CTRL_RESERVED);
}
/**
* @brief Transmit a single data byte through the UART peripheral
* @param pUART : Pointer to selected UART peripheral
* @param data : Byte to transmit
* @return Nothing
* @note This function attempts to place a byte into the UART transmit
* holding register regard regardless of UART state.
*/
STATIC INLINE void Chip_UART_SendByte(LPC_USART_T *pUART, uint8_t data)
{
pUART->TXDATA = (uint32_t) data;
}
/**
* @brief Read a single byte data from the UART peripheral
* @param pUART : Pointer to selected UART peripheral
* @return A single byte of data read
* @note This function reads a byte from the UART receive FIFO or
* receive hold register regard regardless of UART state. The
* FIFO status should be read first prior to using this function
*/
STATIC INLINE uint32_t Chip_UART_ReadByte(LPC_USART_T *pUART)
{
/* Strip off undefined reserved bits, keep 9 lower bits */
return (uint32_t) (pUART->RXDATA & 0x000001FF);
}
/**
* @brief Enable UART interrupts
* @param pUART : Pointer to selected UART peripheral
* @param intMask : OR'ed Interrupts to enable
* @return Nothing
* @note Use an OR'ed value of UART_INTEN_* definitions with this function
* to enable specific UART interrupts.
*/
STATIC INLINE void Chip_UART_IntEnable(LPC_USART_T *pUART, uint32_t intMask)
{
pUART->INTENSET = intMask;
}
/**
* @brief Disable UART interrupts
* @param pUART : Pointer to selected UART peripheral
* @param intMask : OR'ed Interrupts to disable
* @return Nothing
* @note Use an OR'ed value of UART_INTEN_* definitions with this function
* to disable specific UART interrupts.
*/
STATIC INLINE void Chip_UART_IntDisable(LPC_USART_T *pUART, uint32_t intMask)
{
pUART->INTENCLR = intMask;
}
/**
* @brief Returns UART interrupts that are enabled
* @param pUART : Pointer to selected UART peripheral
* @return Returns the enabled UART interrupts
* @note Use an OR'ed value of UART_INTEN_* definitions with this function
* to determine which interrupts are enabled. You can check
* for multiple enabled bits if needed.
*/
STATIC INLINE uint32_t Chip_UART_GetIntsEnabled(LPC_USART_T *pUART)
{
return (pUART->INTENSET & ~UART_INTEN_RESERVED);
}
/**
* @brief Get UART interrupt status
* @param pUART : The base of UART peripheral on the chip
* @return The Interrupt status register of UART
* @note Multiple interrupts may be pending. Mask the return value
* with one or more UART_INTEN_* definitions to determine
* pending interrupts.
*/
STATIC INLINE uint32_t Chip_UART_GetIntStatus(LPC_USART_T *pUART)
{
return (pUART->INTSTAT & ~UART_INTSTAT_RESERVED);
}
/**
* @brief Configure data width, parity and stop bits
* @param pUART : Pointer to selected pUART peripheral
* @param config : UART configuration, OR'ed values of select UART_CFG_* defines
* @return Nothing
* @note Select OR'ed config options for the UART from the UART_CFG_PARITY_*,
* UART_CFG_STOPLEN_*, and UART_CFG_DATALEN_* definitions. For example,
* a configuration of 8 data bits, 1 stop bit, and even (enabled) parity would be
* (UART_CFG_DATALEN_8 | UART_CFG_STOPLEN_1 | UART_CFG_PARITY_EVEN). Will not
* alter other bits in the CFG register.
*/
STATIC INLINE void Chip_UART_ConfigData(LPC_USART_T *pUART, uint32_t config)
{
uint32_t reg;
reg = pUART->CFG & ~((0x3 << 2) | (0x3 << 4) | (0x1 << 6) | UART_CFG_RESERVED);
pUART->CFG = reg | config;
}
/**
* @brief Get the UART status register
* @param pUART : Pointer to selected UARTx peripheral
* @return UART status register
* @note Multiple statuses may be pending. Mask the return value
* with one or more UART_STAT_* definitions to determine
* statuses.
*/
STATIC INLINE uint32_t Chip_UART_GetStatus(LPC_USART_T *pUART)
{
return (pUART->STAT & ~UART_STAT_RESERVED);
}
/**
* @brief Clear the UART status register
* @param pUART : Pointer to selected UARTx peripheral
* @param stsMask : OR'ed statuses to disable
* @return Nothing
* @note Multiple interrupts may be pending. Mask the return value
* with one or more UART_INTEN_* definitions to determine
* pending interrupts.
*/
STATIC INLINE void Chip_UART_ClearStatus(LPC_USART_T *pUART, uint32_t stsMask)
{
pUART->STAT = stsMask;
}
/**
* @brief Set oversample value
* @param pUART : Pointer to selected UARTx peripheral
* @param ovrVal : Oversample value (can be from 5 to 16)
* @return Nothing
* @note The valid values for ovrVal is 5 to 16 (samples per bit)
*/
STATIC INLINE void Chip_UART_SetOSR(LPC_USART_T *pUART, uint32_t ovrVal)
{
pUART->OSR = ovrVal - 1;
}
/**
* @brief Set address for hardware address matching
* @param pUART : Pointer to selected UARTx peripheral
* @param addr : Address to compare (0x00 to 0xFF)
* @return Nothing
* @note The valid values for addr is 0x00 to 0xFF
*/
STATIC INLINE void Chip_UART_SetAddr(LPC_USART_T *pUART, uint32_t addr)
{
pUART->ADDR = addr;
}
/**
* @brief Initialize the UART peripheral
* @param pUART : The base of UART peripheral on the chip
* @return Nothing
*/
void Chip_UART_Init(LPC_USART_T *pUART);
/**
* @brief Deinitialize the UART peripheral
* @param pUART : The base of UART peripheral on the chip
* @return Nothing
*/
void Chip_UART_DeInit(LPC_USART_T *pUART);
/**
* @brief Transmit a byte array through the UART peripheral (non-blocking)
* @param pUART : Pointer to selected UART peripheral
* @param data : Pointer to bytes to transmit
* @param numBytes : Number of bytes to transmit
* @return The actual number of bytes placed into the FIFO
* @note This function places data into the transmit FIFO until either
* all the data is in the FIFO or the FIFO is full. This function
* will not block in the FIFO is full. The actual number of bytes
* placed into the FIFO is returned. This function ignores errors.
*/
int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes);
/**
* @brief Read data through the UART peripheral (non-blocking)
* @param pUART : Pointer to selected UART peripheral
* @param data : Pointer to bytes array to fill
* @param numBytes : Size of the passed data array
* @return The actual number of bytes read
* @note This function reads data from the receive FIFO until either
* all the data has been read or the passed buffer is completely full.
* This function will not block. This function ignores errors.
*/
int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes);
/**
* @brief Set baud rate for UART
* @param pUART : The base of UART peripheral on the chip
* @param baudrate: Baud rate to be set
* @return Nothing
*/
void Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate);
/**
* @brief Transmit a byte array through the UART peripheral (blocking)
* @param pUART : Pointer to selected UART peripheral
* @param data : Pointer to data to transmit
* @param numBytes : Number of bytes to transmit
* @return The number of bytes transmitted
* @note This function will send or place all bytes into the transmit
* FIFO. This function will block until the last bytes are in the FIFO.
*/
int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes);
/**
* @brief Read data through the UART peripheral (blocking)
* @param pUART : Pointer to selected UART peripheral
* @param data : Pointer to data array to fill
* @param numBytes : Size of the passed data array
* @return The size of the dat array
* @note This function reads data from the receive FIFO until the passed
* buffer is completely full. The function will block until full.
* This function ignores errors.
*/
int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes);
/**
* @brief UART receive-only interrupt handler for ring buffers
* @param pUART : Pointer to selected UART peripheral
* @param pRB : Pointer to ring buffer structure to use
* @return Nothing
* @note If ring buffer support is desired for the receive side
* of data transfer, the UART interrupt should call this
* function for a receive based interrupt status.
*/
void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB);
/**
* @brief UART transmit-only interrupt handler for ring buffers
* @param pUART : Pointer to selected UART peripheral
* @param pRB : Pointer to ring buffer structure to use
* @return Nothing
* @note If ring buffer support is desired for the transmit side
* of data transfer, the UART interrupt should call this
* function for a transmit based interrupt status.
*/
void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB);
/**
* @brief Populate a transmit ring buffer and start UART transmit
* @param pUART : Pointer to selected UART peripheral
* @param pRB : Pointer to ring buffer structure to use
* @param data : Pointer to buffer to move to ring buffer
* @param count : Number of bytes to move
* @return The number of bytes placed into the ring buffer
* @note Will move the data into the TX ring buffer and start the
* transfer. If the number of bytes returned is less than the
* number of bytes to send, the ring buffer is considered full.
*/
uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int count);
/**
* @brief Copy data from a receive ring buffer
* @param pUART : Pointer to selected UART peripheral
* @param pRB : Pointer to ring buffer structure to use
* @param data : Pointer to buffer to fill from ring buffer
* @param bytes : Size of the passed buffer in bytes
* @return The number of bytes placed into the ring buffer
* @note Will move the data from the RX ring buffer up to the
* the maximum passed buffer size. Returns 0 if there is
* no data in the ring buffer.
*/
int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes);
/**
* @brief UART receive/transmit interrupt handler for ring buffers
* @param pUART : Pointer to selected UART peripheral
* @param pRXRB : Pointer to transmit ring buffer
* @param pTXRB : Pointer to receive ring buffer
* @return Nothing
* @note This provides a basic implementation of the UART IRQ
* handler for support of a ring buffer implementation for
* transmit and receive.
*/
void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __UART_8XX_H_ */

View File

@ -0,0 +1,81 @@
/*
* @brief LPC8xx Self Wakeup Timer (WKT) chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Set clock source for WKT */
void Chip_WKT_SetClockSource(LPC_WKT_T *pWKT, WKT_CLKSRC_T clkSrc)
{
if (clkSrc == WKT_CLKSRC_10KHZ) {
pWKT->CTRL |= WKT_CTRL_CLKSEL; /* using Low Power clock 10kHz */
}
else {
pWKT->CTRL &= ~WKT_CTRL_CLKSEL; /* using Divided IRC clock 750kHz */
}
}
/* Return approximate rate for the selected clock source */
uint32_t Chip_WKT_GetClockRate(LPC_WKT_T *pWKT)
{
if (Chip_WKT_GetClockSource(pWKT) == WKT_CLKSRC_DIVIRC) {
/* Approximately 750KHz */
return (750 * 1000);
}
else {
/* Approximately 10KHz */
return (10 * 1000);
}
}
/* Start wake-up timer interrupt, set clock source, set timer interval */
void Chip_WKT_Start(LPC_WKT_T *pWKT, WKT_CLKSRC_T clkSrc, uint32_t cntVal)
{
/* Set the WKT clock source */
Chip_WKT_SetClockSource(pWKT, (WKT_CLKSRC_T) clkSrc);
/* Set the WKT counter & start it */
pWKT->COUNT = cntVal;
}

View File

@ -0,0 +1,155 @@
/*
* @brief LPC8xx Self Wakeup Timer (WKT) chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __WKT_8XX_H_
#define __WKT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup WKT_8XX CHIP: LPC8xx Self Wakeup Timer driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Self wake-up timer register block structure
*/
typedef struct {
__IO uint32_t CTRL; /*!< Offset: 0x000 Alarm/Wakeup Timer Control register */
uint32_t Reserved[2];
__IO uint32_t COUNT; /*!< Offset: 0x000C Alarm/Wakeup Timer Counter register */
} LPC_WKT_T;
#define WKT_CTRL_RESERVED (~7)
/**
* WKT Control register bit fields & masks
*/
#define WKT_CTRL_CLKSEL ((uint32_t) (1 << 0)) /*!< Select the self wake-up timer clock source */
#define WKT_CTRL_ALARMFLAG ((uint32_t) (1 << 1)) /*!< Wake-up or alarm timer flag */
#define WKT_CTRL_CLEARCTR ((uint32_t) (1 << 2)) /*!< Clears the self wake-up timer */
/**
* WKT Clock source values enum
*/
typedef enum {
WKT_CLKSRC_DIVIRC = 0, /*!< Divided IRC clock - runs at 750kHz */
WKT_CLKSRC_10KHZ = 1 /*!< Low power clock - runs at 10kHz */
} WKT_CLKSRC_T;
/**
* @brief Get clock source for WKT
* @param pWKT : Pointer to WKT register block
* @return Clock source for the WKT
*/
STATIC INLINE WKT_CLKSRC_T Chip_WKT_GetClockSource(LPC_WKT_T *pWKT)
{
return (WKT_CLKSRC_T) (pWKT->CTRL & WKT_CTRL_CLKSEL);
}
/**
* @brief Set clock source for WKT
* @param pWKT : Pointer to WKT register block
* @param clkSrc : Clock source for the WKT
* @return Nothing
*/
void Chip_WKT_SetClockSource(LPC_WKT_T *pWKT, WKT_CLKSRC_T clkSrc);
/**
* @brief Return approximate rate for the selected clock source
* @param pWKT : Pointer to WKT register block
* @return Clock rate of the selected clock source for WKT
*/
uint32_t Chip_WKT_GetClockRate(LPC_WKT_T *pWKT);
/**
* @brief Get WKT interrupt pending status (ALARMFLAG)
* @param pWKT : Pointer to WKT register block
* @return True if the interrupt is pending, otherwise false
*/
STATIC INLINE bool Chip_WKT_GetIntStatus(LPC_WKT_T *pWKT)
{
return (bool) ((pWKT->CTRL & WKT_CTRL_ALARMFLAG) != 0);
}
/**
* @brief Clear WKT interrupt status (ALARMFLAG)
* @param pWKT : Pointer to WKT register block
* @return Nothing
*/
STATIC INLINE void Chip_WKT_ClearIntStatus(LPC_WKT_T *pWKT)
{
pWKT->CTRL = WKT_CTRL_ALARMFLAG | (pWKT->CTRL & ~WKT_CTRL_RESERVED);
}
/**
* @brief Clear and stop WKT counter
* @param pWKT : Pointer to WKT register block
* @return Nothing
*/
STATIC INLINE void Chip_WKT_Stop(LPC_WKT_T *pWKT)
{
pWKT->CTRL = WKT_CTRL_CLEARCTR | (pWKT->CTRL & ~WKT_CTRL_RESERVED);
}
/**
* @brief Load count register and start count-down sequence
* @param pWKT : Pointer to WKT register block
* @param count : Count to load in the WKT
* @return Nothing
* @note This function should not be called if the WKT is already counting.
*/
STATIC INLINE void Chip_WKT_LoadCount(LPC_WKT_T *pWKT, uint32_t count)
{
pWKT->COUNT = count;
}
/**
* @brief Start wake-up timer interrupt, set clock source, set timer interval
* @param pWKT : Pointer to WKT register block
* @param clkSrc : Clock source
* @param cntVal : Timer interval
* @return None
* @note This function should not be called if the WKT is already counting.
*/
void Chip_WKT_Start(LPC_WKT_T *pWKT, WKT_CLKSRC_T clkSrc, uint32_t cntVal);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __WKT_8XX_H_ */

View File

@ -0,0 +1,78 @@
/*
* @brief LPC8xx WWDT chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the Watchdog timer */
void Chip_WWDT_Init(LPC_WWDT_T *pWWDT)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_WWDT);
/* Disable watchdog */
pWWDT->MOD = 0;
pWWDT->TC = 0xFF;
pWWDT->WARNINT = 0xFFFF;
pWWDT->WINDOW = 0xFFFFFF;
}
/* Shutdown the Watchdog timer */
void Chip_WWDT_DeInit(LPC_WWDT_T *pWWDT)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_WWDT);
}
/* Clear WWDT interrupt status flags */
void Chip_WWDT_ClearStatusFlag(LPC_WWDT_T *pWWDT, uint32_t status)
{
if (status & WWDT_WDMOD_WDTOF) {
pWWDT->MOD &= (~WWDT_WDMOD_WDTOF) & WWDT_WDMOD_BITMASK;
}
if (status & WWDT_WDMOD_WDINT) {
pWWDT->MOD = WWDT_WDMOD_WDINT | (pWWDT->MOD & ~WWDT_MOD_RESERVED);
}
}

View File

@ -0,0 +1,226 @@
/*
* @brief LPC8xx WWDT chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __WWDT_8XX_H_
#define __WWDT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup LPC_WWDT CHIP: LPC8xx Windowed Watchdog driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/*!< WDT oscillator frequency value */
#define WDT_OSC (LPC8XX_IRC_FREQ)
/**
* @brief Windowed Watchdog register block structure
*/
typedef struct { /*!< WWDT Structure */
__IO uint32_t MOD; /*!< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */
__IO uint32_t TC; /*!< Watchdog timer constant register. This register determines the time-out value. */
__O uint32_t FEED; /*!< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC. */
__I uint32_t TV; /*!< Watchdog timer value register. This register reads out the current value of the Watchdog timer. */
__I uint32_t RESERVED0;
__IO uint32_t WARNINT; /*!< Watchdog warning interrupt register. This register contains the Watchdog warning interrupt compare value. */
__IO uint32_t WINDOW; /*!< Watchdog timer window register. This register contains the Watchdog window value. */
} LPC_WWDT_T;
/* Reserved bits masks for registers */
#define WWDT_MOD_RESERVED (~0x3f)
#define WWDT_TC_RESERVED 0xff000000
#define WWDT_FEED_RESERVED (~0xff)
#define WWDT_TV_RESERVED 0xff000000
#define WWDT_WARNINT_RESERVED (~0x3ff)
#define WWDT_WINDOW_RESERVED 0xff000000
/**
* @brief Watchdog Mode register definitions
*/
/** Watchdog Mode Bitmask */
#define WWDT_WDMOD_BITMASK ((uint32_t) 0x1F)
/** WWDT interrupt enable bit */
#define WWDT_WDMOD_WDEN ((uint32_t) (1 << 0))
/** WWDT interrupt enable bit */
#define WWDT_WDMOD_WDRESET ((uint32_t) (1 << 1))
/** WWDT time out flag bit */
#define WWDT_WDMOD_WDTOF ((uint32_t) (1 << 2))
/** WDT Time Out flag bit */
#define WWDT_WDMOD_WDINT ((uint32_t) (1 << 3))
/**
* @brief Initialize the Watchdog timer
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return None
*/
void Chip_WWDT_Init(LPC_WWDT_T *pWWDT);
/**
* @brief Shutdown the Watchdog timer
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return None
*/
void Chip_WWDT_DeInit(LPC_WWDT_T *pWWDT);
/**
* @brief Set WDT timeout constant value used for feed
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param timeout : WDT timeout in ticks, between WWDT_TICKS_MIN and WWDT_TICKS_MAX
* @return none
*/
STATIC INLINE void Chip_WWDT_SetTimeOut(LPC_WWDT_T *pWWDT, uint32_t timeout)
{
pWWDT->TC = timeout;
}
/**
* @brief Feed watchdog timer
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return None
* @note If this function isn't called, a watchdog timer warning will occur.
* After the warning, a timeout will occur if a feed has happened.
*/
STATIC INLINE void Chip_WWDT_Feed(LPC_WWDT_T *pWWDT)
{
pWWDT->FEED = 0xAA;
pWWDT->FEED = 0x55;
}
/**
* @brief Set WWDT warning interrupt
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param timeout : WDT warning in ticks, between 0 and 1023
* @return None
* @note This is the number of ticks after the watchdog interrupt that the
* warning interrupt will be generated.
*/
STATIC INLINE void Chip_WWDT_SetWarning(LPC_WWDT_T *pWWDT, uint32_t timeout)
{
pWWDT->WARNINT = timeout;
}
/**
* @brief Set WWDT window time
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param timeout : WDT timeout in ticks, between WWDT_TICKS_MIN and WWDT_TICKS_MAX
* @return None
* @note The watchdog timer must be fed between the timeout from the Chip_WWDT_SetTimeOut()
* function and this function, with this function defining the last tick before the
* watchdog window interrupt occurs.
*/
STATIC INLINE void Chip_WWDT_SetWindow(LPC_WWDT_T *pWWDT, uint32_t timeout)
{
pWWDT->WINDOW = timeout;
}
/**
* @brief Enable watchdog timer options
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param options : An or'ed set of options of values
* WWDT_WDMOD_WDEN, WWDT_WDMOD_WDRESET, and WWDT_WDMOD_WDPROTECT
* @return None
* @note You can enable more than one option at once (ie, WWDT_WDMOD_WDRESET |
* WWDT_WDMOD_WDPROTECT), but use the WWDT_WDMOD_WDEN after all other options
* are set (or unset) with no other options. If WWDT_WDMOD_LOCK is used, it cannot
* be unset.
*/
STATIC INLINE void Chip_WWDT_SetOption(LPC_WWDT_T *pWWDT, uint32_t options)
{
pWWDT->MOD = options | (pWWDT->MOD & ~WWDT_MOD_RESERVED);
}
/**
* @brief Disable/clear watchdog timer options
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param options : An or'ed set of options of values
* WWDT_WDMOD_WDEN, WWDT_WDMOD_WDRESET, and WWDT_WDMOD_WDPROTECT
* @return None
* @note You can disable more than one option at once (ie, WWDT_WDMOD_WDRESET |
* WWDT_WDMOD_WDTOF).
*/
STATIC INLINE void Chip_WWDT_UnsetOption(LPC_WWDT_T *pWWDT, uint32_t options)
{
pWWDT->MOD &= (~options) & WWDT_WDMOD_BITMASK;
}
/**
* @brief Enable WWDT activity
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return None
*/
STATIC INLINE void Chip_WWDT_Start(LPC_WWDT_T *pWWDT)
{
Chip_WWDT_SetOption(pWWDT, WWDT_WDMOD_WDEN);
Chip_WWDT_Feed(pWWDT);
}
/**
* @brief Read WWDT status flag
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return Watchdog status, an Or'ed value of WWDT_WDMOD_*
*/
STATIC INLINE uint32_t Chip_WWDT_GetStatus(LPC_WWDT_T *pWWDT)
{
return pWWDT->MOD;
}
/**
* @brief Clear WWDT interrupt status flags
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @param status : Or'ed value of status flag(s) that you want to clear, should be:
* - WWDT_WDMOD_WDTOF: Clear watchdog timeout flag
* - WWDT_WDMOD_WDINT: Clear watchdog warning flag
* @return None
*/
void Chip_WWDT_ClearStatusFlag(LPC_WWDT_T *pWWDT, uint32_t status);
/**
* @brief Get the current value of WDT
* @param pWWDT : The base of WatchDog Timer peripheral on the chip
* @return current value of WDT
*/
STATIC INLINE uint32_t Chip_WWDT_GetCurrentCount(LPC_WWDT_T *pWWDT)
{
return pWWDT->TV;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __WWDT_8XX_H_ */

14
bsp/lpc824/SConscript Normal file
View File

@ -0,0 +1,14 @@
# for module compiling
import os
Import('RTT_ROOT')
cwd = str(Dir('#'))
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

37
bsp/lpc824/SConstruct Normal file
View File

@ -0,0 +1,37 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
#RTT_ROOT = os.path.join(Dir('#').get_abspath(), 'rt-thread')
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
print RTT_ROOT
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread-lpc842.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM == 'iar':
env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map'])
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,11 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = os.path.join(str(Dir('#')), 'applications')
src = Glob('*.c')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,57 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard the first version
* 2014-04-27 Bernard make code cleanup.
*/
#include <board.h>
#include <rtthread.h>
#ifndef RT_USING_HEAP
/* if there is not enable heap, we should use static thread and stack. */
ALIGN(8)
static rt_uint8_t init_stack[512];
static struct rt_thread init_thread;
#endif
void rt_init_thread_entry(void* parameter)
{
/* initialization RT-Thread Components */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_init();
#endif
}
int rt_application_init()
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, RT_THREAD_PRIORITY_MAX/3, 20);
#else
{
rt_err_t result;
tid = &init_thread;
result = rt_thread_init(tid, "init", rt_init_thread_entry, RT_NULL,
init_stack, sizeof(init_stack), RT_THREAD_PRIORITY_MAX / 3, 20);
RT_ASSERT(result == RT_EOK);
}
#endif
if (tid != RT_NULL)
rt_thread_startup(tid);
return 0;
}

View File

@ -0,0 +1,107 @@
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-08-31 Bernard first implementation
* 2011-06-05 Bernard modify for STM32F107 version
*/
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
/**
* @addtogroup STM32
*/
/*@{*/
extern int rt_application_init(void);
#ifdef RT_USING_FINSH
extern void finsh_system_init(void);
extern void finsh_set_device(const char* device);
#endif
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert error has occurred.
* Input : - file: pointer to the source file name
* - line: assert error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(uint8_t* file, uint32_t line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
}
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
/* init board */
rt_hw_board_init();
/* show version */
rt_show_version();
/* init tick */
rt_system_tick_init();
/* init kernel object */
rt_system_object_init();
/* init timer system */
rt_system_timer_init();
#ifdef RT_USING_HEAP
rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END);
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* init application */
rt_application_init();
/* init timer thread */
rt_system_timer_thread_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* startup RT-Thread RTOS */
rtthread_startup();
return 0;
}
/*@}*/

View File

@ -0,0 +1,17 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = os.path.join(str(Dir('#')), 'drivers')
# add the general drivers.
src = Split("""
board.c
usart.c
""")
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,75 @@
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009 RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
*/
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "board_lpc.h"
#include "usart.h"
void _init(void)
{
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler */
}
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
/* re-implement tick interface for STM32 HAL */
/**
* This function will initial STM32 board.
*/
void rt_hw_board_init()
{
SysTick_Config(SystemCoreClock / RT_TIMER_TICK_PER_SECOND);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
}
/*@}*/

View File

@ -0,0 +1,42 @@
/*
* File : board.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-09-22 Bernard add board.h to this bsp
*/
// <<< Use Configuration Wizard in Context Menu >>>
#ifndef __BOARD_H__
#define __BOARD_H__
#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#else
extern int __bss_end;
#define HEAP_BEGIN (&__bss_end)
#endif
#define LPC824_SRAM_SIZE 8
#define LPC824_SRAM_END (0x10000000 + LPC824_SRAM_SIZE * 1024)
#define HEAP_END LPC824_SRAM_END
void rt_hw_board_init(void);
void Error_Handler(void);
#endif
//*** <<< end of configuration section >>> ***

337
bsp/lpc824/drivers/usart.c Normal file
View File

@ -0,0 +1,337 @@
/*
* File : usart.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006-2013, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2017-07-28 Tanek the first version
*/
#include <rtthread.h>
#include "usart.h"
#include "peri_driver.h"
#ifdef RT_USING_UART
#ifdef RT_USING_DEVICE
#include <rtdevice.h>
#endif
#define UART_RX_BUFSZ 8
/* STM32 uart driver */
struct stm32_uart
{
struct rt_device parent;
struct rt_ringbuffer rx_rb;
LPC_USART_T * uart_base;
IRQn_Type uart_irq;
rt_uint8_t rx_buffer[UART_RX_BUFSZ];
};
#ifdef RT_USING_UART0
struct stm32_uart uart0_device;
#endif
#ifdef RT_USING_UART1
struct stm32_uart uart1_device;
#endif
#ifdef RT_USING_UART2
struct stm32_uart uart2_device;
#endif
void uart_irq_handler(struct stm32_uart* uart)
{
uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
status = Chip_UART_GetStatus(uart->uart_base);
if(status & UART_STAT_RXRDY) // RXIRQ
{
rt_ringbuffer_putchar_force(&(uart->rx_rb), (rt_uint8_t)Chip_UART_ReadByte(uart->uart_base));
/* invoke callback */
if(uart->parent.rx_indicate != RT_NULL)
{
uart->parent.rx_indicate(&uart->parent, rt_ringbuffer_data_len(&uart->rx_rb));
}
}
/* leave interrupt */
rt_interrupt_leave();
}
#ifdef RT_USING_UART0
void UART0_IRQHandler(void)
{
uart_irq_handler(&uart0_device);
}
#endif
#ifdef RT_USING_UART1
void UART1_IRQHandler(void)
{
uart_irq_handler(&uart1_device);
}
#endif
#ifdef RT_USING_UART2
void UART2_IRQHandler(void)
{
uart_irq_handler(&uart2_device);
}
#endif
static void uart1_io_init(LPC_USART_T * uart_base)
{
/* Enable the clock to the Switch Matrix */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_Clock_SetUARTClockDiv(1);
#ifdef RT_USING_UART0
if (uart_base == LPC_USART0)
{
Chip_SWM_MovablePinAssign(SWM_U0_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U0_RXD_I, 0);
}
else
#endif
#ifdef RT_USING_UART1
if (uart_base == LPC_USART1)
{
Chip_SWM_MovablePinAssign(SWM_U1_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U1_RXD_I, 0);
}
else
#endif
#ifdef RT_USING_UART2
if (uart_base == LPC_USART2)
{
Chip_SWM_MovablePinAssign(SWM_U2_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U2_RXD_I, 0);
}
else
#endif
{
RT_ASSERT((uart_base == USART0) || (uart_base == USART2) || (uart_base == USART2));
}
/* Disable the clock to the Switch Matrix to save power */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
}
static void uart_ll_init(LPC_USART_T * uart)
{
Chip_UART_Init(uart);
Chip_UART_ConfigData(uart, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1);
Chip_Clock_SetUSARTNBaseClockRate((115200 * 6 * 16), true);
Chip_UART_SetBaud(uart, 115200);
Chip_UART_Enable(uart);
Chip_UART_TXEnable(uart);
// we must NOT enable TX ready/idle IRQ before we want to write data
// otherwise the IRQs will happen as soon as Uart IRQ is enabled in NVIC
Chip_UART_IntDisable(uart, UART_INTEN_TXRDY | UART_INTEN_TXIDLE);
Chip_UART_IntEnable(uart, UART_INTEN_RXRDY);
}
static rt_err_t rt_uart_init (rt_device_t dev)
{
struct stm32_uart* uart;
RT_ASSERT(dev != RT_NULL);
uart = (struct stm32_uart *)dev;
uart1_io_init(uart->uart_base);
uart_ll_init(uart->uart_base);
return RT_EOK;
}
static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
{
struct stm32_uart* uart;
RT_ASSERT(dev != RT_NULL);
uart = (struct stm32_uart *)dev;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* Enable the UART Interrupt */
NVIC_EnableIRQ(uart->uart_irq);
}
return RT_EOK;
}
static rt_err_t rt_uart_close(rt_device_t dev)
{
struct stm32_uart* uart;
RT_ASSERT(dev != RT_NULL);
uart = (struct stm32_uart *)dev;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* Disable the UART Interrupt */
NVIC_DisableIRQ(uart->uart_irq);
}
return RT_EOK;
}
static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
/* interrupt receive */
rt_base_t level;
rt_size_t length;
struct stm32_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct stm32_uart *)dev;
RT_ASSERT(uart != RT_NULL);
/* disable interrupt */
level = rt_hw_interrupt_disable();
length = rt_ringbuffer_get(&(uart->rx_rb), buffer, size);
/* enable interrupt */
rt_hw_interrupt_enable(level);
return length;
}
static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
char *ptr = (char*) buffer;
struct stm32_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct stm32_uart *)dev;
if (dev->open_flag & RT_DEVICE_FLAG_STREAM)
{
/* stream mode */
while (size)
{
if (*ptr == '\n')
{
while (!(Chip_UART_GetStatus(uart->uart_base) & UART_STAT_TXRDY));
Chip_UART_SendByte(uart->uart_base, '\r');
}
while (!(Chip_UART_GetStatus(uart->uart_base) & UART_STAT_TXRDY));
Chip_UART_SendByte(uart->uart_base, *ptr);
ptr ++;
size --;
}
}
else
{
while (size)
{
while (!(Chip_UART_GetStatus(uart->uart_base) & UART_STAT_TXRDY));
Chip_UART_SendByte(uart->uart_base, *ptr);
ptr++;
size--;
}
}
return (rt_size_t) ptr - (rt_size_t) buffer;
}
int rt_hw_usart_init(void)
{
#ifdef RT_USING_UART0
{
struct stm32_uart* uart;
/* get uart device */
uart = &uart1_device;
/* device initialization */
uart->parent.type = RT_Device_Class_Char;
uart->uart_base = LPC_USART0;
uart->uart_irq = UART0_IRQn;
rt_ringbuffer_init(&(uart->rx_rb), uart->rx_buffer, sizeof(uart->rx_buffer));
/* device interface */
uart->parent.init = rt_uart_init;
uart->parent.open = rt_uart_open;
uart->parent.close = rt_uart_close;
uart->parent.read = rt_uart_read;
uart->parent.write = rt_uart_write;
uart->parent.control = RT_NULL;
uart->parent.user_data = RT_NULL;
rt_device_register(&uart->parent, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
}
#endif
#ifdef RT_USING_UART1
{
struct stm32_uart* uart;
/* get uart device */
uart = &uart1_device;
/* device initialization */
uart->parent.type = RT_Device_Class_Char;
uart->uart_base = LPC_USART1;
uart->uart_irq = UART1_IRQn;
rt_ringbuffer_init(&(uart->rx_rb), uart->rx_buffer, sizeof(uart->rx_buffer));
/* device interface */
uart->parent.init = rt_uart_init;
uart->parent.open = rt_uart_open;
uart->parent.close = rt_uart_close;
uart->parent.read = rt_uart_read;
uart->parent.write = rt_uart_write;
uart->parent.control = RT_NULL;
uart->parent.user_data = RT_NULL;
rt_device_register(&uart->parent, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
}
#endif
#ifdef RT_USING_UART2
{
struct stm32_uart* uart;
/* get uart device */
uart = &uart2_device;
/* device initialization */
uart->parent.type = RT_Device_Class_Char;
uart->uart_base = LPC_USART1;
uart->uart_irq = UART2_IRQn;
rt_ringbuffer_init(&(uart->rx_rb), uart->rx_buffer, sizeof(uart->rx_buffer));
/* device interface */
uart->parent.init = rt_uart_init;
uart->parent.open = rt_uart_open;
uart->parent.close = rt_uart_close;
uart->parent.read = rt_uart_read;
uart->parent.write = rt_uart_write;
uart->parent.control = RT_NULL;
uart->parent.user_data = RT_NULL;
rt_device_register(&uart->parent, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
}
#endif /* RT_USING_UART2 */
return 0;
}
INIT_BOARD_EXPORT(rt_hw_usart_init);
#endif /*RT_USING_UART*/

View File

@ -0,0 +1,23 @@
/*
* File : usart.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2013-11-15 bright the first version
*/
#ifndef __USART_H__
#define __USART_H__
#include <rthw.h>
#include <rtthread.h>
int rt_hw_usart_init(void);
#endif

34
bsp/lpc824/lpc824_rom.icf Normal file
View File

@ -0,0 +1,34 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x00007FFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x1000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_heap__ = 0x000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
define block RTT_INIT_FUNC with fixed order { readonly section .rti_fn* };
initialize by copy { readwrite };
do not initialize { section .noinit };
keep { section FSymTab };
keep { section VSymTab };
keep { section .rti_fn* };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly, block RTT_INIT_FUNC };
place in RAM_region { readwrite, block CSTACK, last block HEAP};

141
bsp/lpc824/lpc824_rom.ld Normal file
View File

@ -0,0 +1,141 @@
/*
* linker script for LPC842 with GNU ld
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
CODE (rx) : ORIGIN = 0x00000000, LENGTH = 32k /* 32k flash */
DATA (rw) : ORIGIN = 0x10000000, LENGTH = 8k /* 8k sram */
}
ENTRY(Reset_Handler)
_system_stack_size = 0x100;
SECTIONS
{
.text :
{
. = ALIGN(4);
_stext = .;
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
. = ALIGN(4);
_etext = .;
} > CODE = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > CODE
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >DATA
.stack :
{
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >DATA
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > DATA
__bss_end = .;
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

15
bsp/lpc824/lpc824_rom.sct Normal file
View File

@ -0,0 +1,15 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00008000 { ; load region size_region
ER_IROM1 0x00000000 0x00008000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x10000000 0x00002000 { ; RW data
.ANY (+RW +ZI)
}
}

2247
bsp/lpc824/project.ewp Normal file

File diff suppressed because it is too large Load Diff

10
bsp/lpc824/project.eww Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\project.ewp</path>
</project>
<batchBuild/>
</workspace>

714
bsp/lpc824/project.uvprojx Normal file
View File

@ -0,0 +1,714 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>RT-Thread LPC82x</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>LPC824M201JHI33</Device>
<Vendor>NXP</Vendor>
<PackID>Keil.LPC800_DFP.1.5.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x10000000,0x00002000) IROM(0x00000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC8xx_32 -FS00 -FL08000 -FP0($$Device:LPC824M201JHI33$Flash\LPC8xx_32.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId>
<RegisterFile>$$Device:LPC824M201JHI33$Device\Include\LPC8xx.h</RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:LPC824M201JHI33$SVD\LPC82x.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath></RegisterFilePath>
<DBRegisterFilePath></DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\build\</OutputDirectory>
<OutputName>rtthread-lpc</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>0</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath>.\build\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments> </SimDllArguments>
<SimDlgDll>DARMCM1.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments> </TargetDllArguments>
<TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4099</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3></Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M0+"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>0</RvdsVP>
<hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>0</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x2000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x8000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x8000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x2000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>3</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>0</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>0</uC99>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>CORE_M0PLUS</Define>
<Undefine></Undefine>
<IncludePath>applications;.;drivers;Libraries\peri_driver;Libraries\common\board;Libraries\common\chip;Libraries\common\CMSIS;..\..\components\CMSIS\Include;..\..\include;..\..\libcpu\arm\cortex-m0;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\finsh</IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<uClangAs>0</uClangAs>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>0</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x00000000</TextAddressRange>
<DataAddressRange>0x10000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile>.\lpc824_rom.sct</ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc>--keep *.o(.rti_fn.*) --keep *.o(FSymTab)</Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>Applications</GroupName>
<Files>
<File>
<FileName>application.c</FileName>
<FileType>1</FileType>
<FilePath>applications\application.c</FilePath>
</File>
<File>
<FileName>startup.c</FileName>
<FileType>1</FileType>
<FilePath>applications\startup.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Drivers</GroupName>
<Files>
<File>
<FileName>board.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\board.c</FilePath>
</File>
<File>
<FileName>usart.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\usart.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Libraries</GroupName>
<Files>
<File>
<FileName>acmp_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\acmp\acmp_8xx.c</FilePath>
</File>
<File>
<FileName>adc_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\adc\adc_8xx.c</FilePath>
</File>
<File>
<FileName>crc_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\crc\crc_8xx.c</FilePath>
</File>
<File>
<FileName>dma_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\dma\dma_8xx.c</FilePath>
</File>
<File>
<FileName>gpio_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\gpio\gpio_8xx.c</FilePath>
</File>
<File>
<FileName>i2c_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\i2c\i2c_8xx.c</FilePath>
</File>
<File>
<FileName>iap.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\iap\iap.c</FilePath>
</File>
<File>
<FileName>stopwatch.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\mrt\stopwatch.c</FilePath>
</File>
<File>
<FileName>pinint_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\pinint\pinint_8xx.c</FilePath>
</File>
<File>
<FileName>pmu_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\pmu\pmu_8xx.c</FilePath>
</File>
<File>
<FileName>sct_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\sctimer\sct_8xx.c</FilePath>
</File>
<File>
<FileName>sct_pwm_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\sctimer\sct_pwm_8xx.c</FilePath>
</File>
<File>
<FileName>spi_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\spi\spi_8xx.c</FilePath>
</File>
<File>
<FileName>ring_buffer.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\uart\ring_buffer.c</FilePath>
</File>
<File>
<FileName>uart_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\uart\uart_8xx.c</FilePath>
</File>
<File>
<FileName>wkt_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\wkt\wkt_8xx.c</FilePath>
</File>
<File>
<FileName>wwdt_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\peri_driver\wwdt\wwdt_8xx.c</FilePath>
</File>
<File>
<FileName>board_lpc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\common\board\board_lpc.c</FilePath>
</File>
<File>
<FileName>clock_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\common\chip\clock_8xx.c</FilePath>
</File>
<File>
<FileName>ioswm_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\common\chip\ioswm_8xx.c</FilePath>
</File>
<File>
<FileName>syscon_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\common\chip\syscon_8xx.c</FilePath>
</File>
<File>
<FileName>sysinit_8xx.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\common\chip\sysinit_8xx.c</FilePath>
</File>
<File>
<FileName>keil_startup_lpc82x.s</FileName>
<FileType>2</FileType>
<FilePath>Libraries\common\startup\keil_startup_lpc82x.s</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Kernel</GroupName>
<Files>
<File>
<FileName>clock.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\clock.c</FilePath>
</File>
<File>
<FileName>components.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\components.c</FilePath>
</File>
<File>
<FileName>device.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\device.c</FilePath>
</File>
<File>
<FileName>idle.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\idle.c</FilePath>
</File>
<File>
<FileName>ipc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\ipc.c</FilePath>
</File>
<File>
<FileName>irq.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\irq.c</FilePath>
</File>
<File>
<FileName>kservice.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\kservice.c</FilePath>
</File>
<File>
<FileName>mem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\mem.c</FilePath>
</File>
<File>
<FileName>object.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\object.c</FilePath>
</File>
<File>
<FileName>scheduler.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\scheduler.c</FilePath>
</File>
<File>
<FileName>thread.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\thread.c</FilePath>
</File>
<File>
<FileName>timer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\timer.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>CORTEX-M0</GroupName>
<Files>
<File>
<FileName>cpuport.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\cortex-m0\cpuport.c</FilePath>
</File>
<File>
<FileName>context_rvds.S</FileName>
<FileType>2</FileType>
<FilePath>..\..\libcpu\arm\cortex-m0\context_rvds.S</FilePath>
</File>
<File>
<FileName>backtrace.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath>
</File>
<File>
<FileName>div0.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\div0.c</FilePath>
</File>
<File>
<FileName>showmem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\showmem.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>DeviceDrivers</GroupName>
<Files>
<File>
<FileName>completion.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\completion.c</FilePath>
</File>
<File>
<FileName>dataqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\dataqueue.c</FilePath>
</File>
<File>
<FileName>pipe.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\pipe.c</FilePath>
</File>
<File>
<FileName>portal.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\portal.c</FilePath>
</File>
<File>
<FileName>ringbuffer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\ringbuffer.c</FilePath>
</File>
<File>
<FileName>workqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\workqueue.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>finsh</GroupName>
<Files>
<File>
<FileName>shell.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\shell.c</FilePath>
</File>
<File>
<FileName>symbol.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\symbol.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\cmd.c</FilePath>
</File>
<File>
<FileName>msh.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\msh.c</FilePath>
</File>
<File>
<FileName>msh_cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\msh_cmd.c</FilePath>
</File>
<File>
<FileName>msh_file.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\msh_file.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
</Group>
</Groups>
</Target>
</Targets>
<RTE>
<apis/>
<components>
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.0.1" condition="ARMv6_7_8-M Device">
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.0.1"/>
<targetInfos>
<targetInfo name="RT-Thread LPC82x"/>
</targetInfos>
</component>
</components>
<files/>
</RTE>
</Project>

188
bsp/lpc824/rtconfig.h Normal file
View File

@ -0,0 +1,188 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
// <<< Use Configuration Wizard in Context Menu >>>
// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
// <i>Default: 32
#define RT_THREAD_PRIORITY_MAX 8
// <o>OS tick per second
// <i>Default: 1000 (1ms)
#define RT_TICK_PER_SECOND 100
// <o>Alignment size for CPU architecture data access
// <i>Default: 4
#define RT_ALIGN_SIZE 4
// <o>the max length of object name<2-16>
// <i>Default: 8
#define RT_NAME_MAX 8
// <c1>Using RT-Thread components initialization
// <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>
// <c1>Using user main
// <i>Using user main
//#define RT_USING_USER_MAIN
// </c>
// <o>the size of main thread<1-4086>
// <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE 256
// </h>
// <h>Debug Configuration
// <c1>enable kernel debug configuration
// <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
// <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
// <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>
// <h>Hook Configuration
// <c1>using hook
// <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
// <i>using idle hook
//#define RT_USING_IDLE_HOOK
// </c>
// </h>
// <e>Software timers Configuration
// <i> Enables user timers
#define RT_USING_TIMER_SOFT 0
#if RT_USING_TIMER_SOFT == 0
#undef RT_USING_TIMER_SOFT
#endif
// <o>The priority level of timer thread <0-31>
// <i>Default: 4
#define RT_TIMER_THREAD_PRIO 4
// <o>The stack size of timer thread <0-8192>
// <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE 512
// <o>The soft-timer tick per second <0-1000>
// <i>Default: 100
#define RT_TIMER_TICK_PER_SECOND 100
// </e>
// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
// <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>
// <c1>Using Mutex
// <i>Using Mutex
//#define RT_USING_MUTEX
// </c>
// <c1>Using Event
// <i>Using Event
//#define RT_USING_EVENT
// </c>
// <c1>Using MailBox
// <i>Using MailBox
#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
// <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>
// <h>Memory Management Configuration
// <c1>Using Memory Pool Management
// <i>Using Memory Pool Management
//#define RT_USING_MEMPOOL
// </c>
// <c1>Dynamic Heap Management
// <i>Dynamic Heap Management
#define RT_USING_HEAP
// </c>
// <c1>using small memory
// <i>using small memory
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
// <i>using tiny size of memory
#define RT_USING_TINY_SIZE
// </c>
// </h>
// <h>Device System Configuration
// <c1>Using Device System
// <i>Using Device System
#define RT_USING_DEVICE
// </c>
// <c1>Using device communication
// <i>Using device communication
#define RT_USING_DEVICE_IPC
// </c>
// <c1>Using Serial
// <i>Using Serial
//#define RT_USING_SERIAL
// </c>
// </h>
// <h>Console Configuration
// <c1>Using console
// <i>Using console
#define RT_USING_CONSOLE
// </c>
// <o>the buffer size of console <1-1024>
// <i>the buffer size of console
// <i>Default: 128 (128Byte)
#define RT_CONSOLEBUF_SIZE 128
// <s>The device name for console
// <i>The device name for console
// <i>Default: uart1
#define RT_CONSOLE_DEVICE_NAME "uart1"
// </h>
// <h>Finsh Configuration
// <c1>Using finsh as shell, which is a C-Express shell
// <i>Using finsh as shell, which is a C-Express shell
#define RT_USING_FINSH
// </c>
// <o>the priority of finsh thread <1-7>
// <i>the priority of finsh thread
// <i>Default: 6
#define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * 5 + 1)
// <o>the stack of finsh thread <1-4096>
// <i>the stack of finsh thread
// <i>Default: 4096 (4096Byte)
#define FINSH_THREAD_STACK_SIZE 512
// <o>the history lines of finsh thread <1-32>
// <i>the history lines of finsh thread
// <i>Default: 5
#define FINSH_HISTORY_LINES 1
// <c1>Using symbol table in finsh shell
// <i>Using symbol table in finsh shell
#define FINSH_USING_SYMTAB
// </c>
// <c1>Using module shell in finsh
// <i>Using module shell in finsh
#define FINSH_USING_MSH
// </c>
// <c1>Only using module shell in finsh
// <i>Only using module shell in finsh
#define FINSH_USING_MSH_ONLY
// </c>
// </h>
// <<< end of configuration section >>>
#define RT_USING_UART
#define RT_USING_UART1
#define RT_USING_RTT_CMSIS
#endif

125
bsp/lpc824/rtconfig.py Normal file
View File

@ -0,0 +1,125 @@
import os
# toolchains options
ARCH='arm'
CPU='cortex-m0'
CROSS_TOOL='keil'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc':
print '================ERROR============================'
print 'Not support gcc yet!'
print '================================================='
elif CROSS_TOOL == 'keil':
PLATFORM = 'armcc'
EXEC_PATH = 'C:/keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iar'
IAR_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
#BUILD = 'debug'
BUILD = 'release'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'axf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=cortex-m0 -mthumb -ffunction-sections -fdata-sections'
CFLAGS = DEVICE
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-lpc824.map,-cref,-u,Reset_Handler -T lpc824_rom.ld'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
elif PLATFORM == 'armcc':
# toolchains
CC = 'armcc'
AS = 'armasm'
AR = 'armar'
LINK = 'armlink'
TARGET_EXT = 'axf'
DEVICE = ' --cpu Cortex-M0+'
CFLAGS = DEVICE + ' --apcs=interwork'
AFLAGS = DEVICE
LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-lpc824.map --scatter lpc824_rom.sct'
CFLAGS += ' -I./'
EXEC_PATH += '/ARM/ARMCC/bin/'
if BUILD == 'debug':
CFLAGS += ' -g -O0'
AFLAGS += ' -g'
else:
CFLAGS += ' -O2'
CFLAGS += ' --split_sections'
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
elif PLATFORM == 'iar':
# toolchains
CC = 'iccarm'
AS = 'iasmarm'
AR = 'iarchive'
LINK = 'ilinkarm'
TARGET_EXT = 'out'
DEVICE = ' -D USE_STDPERIPH_DRIVER'
CFLAGS = DEVICE
CFLAGS += ' --diag_suppress Pa050'
CFLAGS += ' --no_cse'
CFLAGS += ' --no_unroll'
CFLAGS += ' --no_inline'
CFLAGS += ' --no_code_motion'
CFLAGS += ' --no_tbaa'
CFLAGS += ' --no_clustering'
CFLAGS += ' --no_scheduling'
CFLAGS += ' --debug'
CFLAGS += ' --endian=little'
CFLAGS += ' --cpu=Cortex-M0'
CFLAGS += ' -e'
CFLAGS += ' --fpu=None'
CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"'
CFLAGS += ' -Ol'
CFLAGS += ' --use_c++_inline'
AFLAGS = ''
AFLAGS += ' -s+'
AFLAGS += ' -w+'
AFLAGS += ' -r'
AFLAGS += ' --cpu Cortex-M0'
AFLAGS += ' --fpu None'
LFLAGS = ' --config lpc824_rom.icf'
LFLAGS += ' --redirect _Printf=_PrintfTiny'
LFLAGS += ' --redirect _Scanf=_ScanfSmall'
LFLAGS += ' --entry __iar_program_start'
EXEC_PATH = IAR_PATH + '/arm/bin/'
POST_ACTION = ''

1819
bsp/lpc824/template.ewp Normal file

File diff suppressed because it is too large Load Diff

399
bsp/lpc824/template.uvprojx Normal file
View File

@ -0,0 +1,399 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>RT-Thread LPC82x</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>LPC824M201JHI33</Device>
<Vendor>NXP</Vendor>
<PackID>Keil.LPC800_DFP.1.5.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x10000000,0x00002000) IROM(0x00000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC8xx_32 -FS00 -FL08000 -FP0($$Device:LPC824M201JHI33$Flash\LPC8xx_32.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId>
<RegisterFile>$$Device:LPC824M201JHI33$Device\Include\LPC8xx.h</RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:LPC824M201JHI33$SVD\LPC82x.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath></RegisterFilePath>
<DBRegisterFilePath></DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\build\</OutputDirectory>
<OutputName>rtthread-lpc</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>0</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath>.\build\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments> </SimDllArguments>
<SimDlgDll>DARMCM1.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments> </TargetDllArguments>
<TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4099</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3></Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M0+"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>0</RvdsVP>
<hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>0</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x2000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x8000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x8000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x2000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>3</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>0</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>0</uC99>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<uClangAs>0</uClangAs>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>0</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x00000000</TextAddressRange>
<DataAddressRange>0x10000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile>.\lpc824_rom.sct</ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc></Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>::CMSIS</GroupName>
</Group>
</Groups>
</Target>
</Targets>
<RTE>
<apis/>
<components>
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.0.1" condition="ARMv6_7_8-M Device">
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.0.1"/>
<targetInfos>
<targetInfo name="RT-Thread LPC82x"/>
</targetInfos>
</component>
</components>
<files/>
</RTE>
</Project>