diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/arm_common_tables.h b/bsp/lpc5410x/Libraries/CMSIS/Include/arm_common_tables.h new file mode 100644 index 0000000000000000000000000000000000000000..7a59b5923e9edcfc684691f70cb06360d20ddfff --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/arm_common_tables.h @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2013 ARM Limited. All rights reserved. +* +* $Date: 17. January 2013 +* $Revision: V1.4.1 +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* 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 LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +extern const q31_t realCoefAQ31[1024]; +extern const q31_t realCoefBQ31[1024]; +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoefQ31[6144]; +extern const q15_t twiddleCoefQ15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/arm_math.h b/bsp/lpc5410x/Libraries/CMSIS/Include/arm_math.h new file mode 100644 index 0000000000000000000000000000000000000000..65304c127d6c5ad0a49cab6b0c30be220035a16a --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/arm_math.h @@ -0,0 +1,7306 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2013 ARM Limited. All rights reserved. +* +* $Date: 17. January 2013 +* $Revision: V1.4.1 +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 +* +* 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 LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * + * Examples + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * + * The library has been developed and tested with MDK-ARM version 4.60. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * + * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM0b_math.uvproj + * - arm_cortexM0l_math.uvproj + * - arm_cortexM3b_math.uvproj + * - arm_cortexM3l_math.uvproj + * - arm_cortexM4b_math.uvproj + * - arm_cortexM4l_math.uvproj + * - arm_cortexM4bf_math.uvproj + * - arm_cortexM4lf_math.uvproj + * + * + * The project can be built by opening the appropriate project in MDK-ARM 4.60 chain and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on cortex-M0 target, ARM_MATH_CM0PLUS for building library on cortex-M0+ target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + * Copyright Notice + * + * Copyright (C) 2010-2013 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined (ARM_MATH_CM4) +#include "core_cm4.h" +#elif defined (ARM_MATH_CM3) +#include "core_cm3.h" +#elif defined (ARM_MATH_CM0) +#include "core_cm0.h" +#define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) +#include "core_cm0plus.h" +#define ARM_MATH_CM0_FAMILY +#else +#include "ARMCM4.h" +#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....." +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x800000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM +#define __SIMD32_TYPE int32_t __packed +#define CMSIS_UNUSED __attribute__((unused)) +#elif defined __ICCARM__ +#define CMSIS_UNUSED +#define __SIMD32_TYPE int32_t __packed +#elif defined __GNUC__ +#define __SIMD32_TYPE int32_t +#define CMSIS_UNUSED __attribute__((unused)) +#else +#error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) + +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) + +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + +#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) ) + + static __INLINE uint32_t __CLZ( + q31_t data); + + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + + } + +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + + uint32_t out, tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = __CLZ(in) - 1; + } + else + { + signBits = __CLZ(-in) - 1; + } + + /* Convert input sample to 1.31 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = (uint32_t) (in >> 24u); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (q31_t) (((q63_t) in * out) >> 31u); + tempVal = 0x7FFFFFFF - tempVal; + /* 1.31 with exp 1 */ + //out = (q31_t) (((q63_t) out * tempVal) >> 30u); + out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + + uint32_t out = 0, tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = __CLZ(in) - 17; + } + else + { + signBits = __CLZ(-in) - 17; + } + + /* Convert input sample to 1.15 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = in >> 8; + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0; i < 2; i++) + { + tempVal = (q15_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFF - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + + + } + +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE q31_t __QADD8( + q31_t x, + q31_t y) + { + + q31_t sum; + q7_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((q31_t) (r + s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); + t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); + u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); + + sum = + (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | + (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); + + return sum; + + } + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB8( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((r - s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; + t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; + u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; + + sum = + (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & + 0x000000FF); + + return sum; + } + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE q31_t __QADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r + s, 16); + s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE q31_t __SHADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (s >> 1)); + s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r - s, 16); + s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __SHSUB16( + q31_t x, + q31_t y) + { + + q31_t diff; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (s >> 1)); + s = (((x >> 17) - (y >> 17)) << 16); + + diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return diff; + } + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE q31_t __QASX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE q31_t __SHASX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (y >> 17)); + s = (((x >> 17) + (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE q31_t __QSAX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE q31_t __SHSAX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (y >> 17)); + s = (((x >> 17) - (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMUSDX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((short) x * (short) (y >> 16)) - + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE q31_t __SMUADX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((short) x * (short) (y >> 16)) + + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE q31_t __QADD( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x + y); + } + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE q31_t __QSUB( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x - y); + } + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE q31_t __SMLAD( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE q31_t __SMLADX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMLSDX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum - ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE q63_t __SMLALD( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE q63_t __SMLALDX( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) y)) + + ((short) x * (short) (y >> 16)); + } + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE q31_t __SMUAD( + q31_t x, + q31_t y) + { + + return (((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE q31_t __SMUSD( + q31_t x, + q31_t y) + { + + return (-((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE q31_t __SXTB16( + q31_t x) + { + + return ((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000)); + } + + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] *S points to an instance of the Q7 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] *S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + * @return none + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] *S points to an instance of the Q15 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] *S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] *S points to an instance of the Q31 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] *S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] *S points to an instance of the floating-point FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] *S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q15; + + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + + + } arm_biquad_casd_df1_inst_f32; + + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q31; + + + + /** + * @brief Floating-point matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] *pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] *pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] *S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @return none + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @return none + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the q15 PID Control structure + * @return none + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + + + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + + + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q31 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q15 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + /** + * @brief Floating-point vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Dot product of floating-point vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + /** + * @brief Dot product of Q7 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + /** + * @brief Dot product of Q15 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Dot product of Q31 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_f32; + + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the Q15 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + * @return none. + */ + + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + + } arm_lms_instance_q31; + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Correlation of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + /** + * @brief Correlation of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /* + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cos output. + * @return none. + */ + + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCcosVal); + + /* + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cosine output. + * @return none. + */ + + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + + + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = __SMLALD(S->A1, (q31_t) *vstate, acc); + +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; + +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] *src points to the instance of the input floating-point matrix structure. + * @param[out] *dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + + /** + * @ingroup groupController + */ + + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + */ + + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = + ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + + } + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + */ + + + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; + + } + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * The function implements the forward Park transform. + * + */ + + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + + } + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + + + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + */ + + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] *pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + + } + + } + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] *pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (y >> 20); + } + + + } + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] *pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + + + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (y >> 20u); + + } + + } + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + + float32_t arm_sin_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q31_t arm_sin_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q15_t arm_sin_q15( + q15_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + + float32_t arm_cos_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q31_t arm_cos_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in > 0) + { + +// #if __FPU_USED +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + + + + + /** + * @brief floating-point Circular write function. + */ + + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + /** + * @brief Q15 Circular write function. + */ + + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + /** + * @brief Mean value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Mean value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Floating-point complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + /** + * @brief Q31 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + /** + * @brief Floating-point complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[in] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + * @return none. + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + + + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 + || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + + } + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20u); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20u); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return (acc << 2u); + + } + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return (acc >> 36); + + } + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return (acc >> 40); + + } + + /** + * @} end of BilinearInterpolate group + */ + + +#if defined ( __CC_ARM ) //Keil +//SMMLAR + #define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +//SMMLSR + #define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +//SMMULR + #define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +//Enter low optimization region - place directly above function definition + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + +//Exit low optimization region - place directly after end of function definition + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + +//Enter low optimization region - place directly above function definition + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + +//Exit low optimization region - place directly after end of function definition + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) //IAR + //SMMLA + #define multAcc_32x32_keep32_R(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + + //SMMLS + #define multSub_32x32_keep32_R(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +//SMMUL + #define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + +//Enter low optimization region - place directly above function definition + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + +//Exit low optimization region - place directly after end of function definition + #define LOW_OPTIMIZATION_EXIT + +//Enter low optimization region - place directly above function definition + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + +//Exit low optimization region - place directly after end of function definition + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + //SMMLA + #define multAcc_32x32_keep32_R(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + + //SMMLS + #define multSub_32x32_keep32_R(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +//SMMUL + #define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + + #define LOW_OPTIMIZATION_EXIT + + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + + +/** + * + * End of file. + */ diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000000000000000000000000000000000000..ab31de0ee87f9cb566cef040364c80c1f09bbf86 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0.h @@ -0,0 +1,682 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "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 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000 + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< 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 15 /*!< 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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \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_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 */ + + +/*@} */ + + + +/******************************************************************************* + * 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)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function 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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0plus.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0plus.h new file mode 100644 index 0000000000000000000000000000000000000000..5cea74e9af368d558cb8fca0b537eb0061006d92 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm0plus.h @@ -0,0 +1,793 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0P definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \ + __CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "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 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000 + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0 + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1) + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8 /*!< 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 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< 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 15 /*!< 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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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_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 == 1) + #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)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function 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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm3.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000000000000000000000000000000000000..122c9aa4a8fd6832d39545a26636a662c7ff317c --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm3.h @@ -0,0 +1,1627 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "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 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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 Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #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 Debug 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. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function 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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000000000000000000000000000000000000..d65016c714944b5eb2d3dac3ea544d0decd231bc --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4.h @@ -0,0 +1,1772 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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 + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug 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. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function 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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4_simd.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4_simd.h new file mode 100644 index 0000000000000000000000000000000000000000..83db95b5f112dd3e86cdc24b885eef66eef4a067 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cm4_simd.h @@ -0,0 +1,673 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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. + ---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#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) << 32) ) >> 32)) + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#include + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#include + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SMLALD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLALDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SMLSLD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLSLDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +/* not yet supported */ +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CORE_CM4_SIMD_H */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmFunc.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmFunc.h new file mode 100644 index 0000000000000000000000000000000000000000..0a18fafc301e003d348edf5cae39481d8e5fe7c3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmFunc.h @@ -0,0 +1,636 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function 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 & 0xff); +} + + +/** \brief Get Fault Mask + + This function 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 + + This function 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 >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmInstr.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmInstr.h new file mode 100644 index 0000000000000000000000000000000000000000..d213f0eed7ca9335e883a5b55b6de14ba9507f1e --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_cmInstr.h @@ -0,0 +1,688 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.20 + * @date 05. March 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#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 + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#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) + + This function 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 + + This function 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) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function 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 + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function 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) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc000.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc000.h new file mode 100644 index 0000000000000000000000000000000000000000..1a2a0f2e300d83548c20c3998765a7e2460925d9 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc000.h @@ -0,0 +1,813 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup SC000 + @{ + */ + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (0) /*!< Cortex secure 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "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 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000 + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1]; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154]; + __IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< 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 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/* SCB Security Features Register Definitions */ +#define SCB_SFCR_UNIBRTIMING_Pos 0 /*!< SCB SFCR: UNIBRTIMING Position */ +#define SCB_SFCR_UNIBRTIMING_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: UNIBRTIMING Mask */ + +#define SCB_SFCR_SECKEY_Pos 16 /*!< SCB SFCR: SECKEY Position */ +#define SCB_SFCR_SECKEY_Msk (0xFFFFUL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: SECKEY Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2]; + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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 SC000 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_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of SC000 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 == 1) + #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)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function 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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc300.h b/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc300.h new file mode 100644 index 0000000000000000000000000000000000000000..cc34d6fc0eee62d3b7f71e7a014417876c4fc277 --- /dev/null +++ b/bsp/lpc5410x/Libraries/CMSIS/Include/core_sc300.h @@ -0,0 +1,1598 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 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 */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +/** \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.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup SC3000 + @{ + */ + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (300) /*!< Cortex secure 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 ( __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 ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU 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 + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "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 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000 + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 + + IO Type Qualifiers 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 */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug 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 + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + 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; + + +/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} 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 +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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 Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #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 Debug 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. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function 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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function 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(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function 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(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} 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 == 0) + +/** \brief System Tick Configuration + + The function 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 __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/lpc5410x/Libraries/Device/SConscript b/bsp/lpc5410x/Libraries/Device/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..40a74f15412fca7d7432a41260965bf7c2257b4d --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/SConscript @@ -0,0 +1,22 @@ +# RT-Thread building script for component + +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +startup/sysinit.c +''') +CPPPATH = [cwd + '/../CMSIS/Include'] +CPPDEFINES = ['CORE_M4'] + + +# add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + src += ['startup/gcc_startup_lpc5410x.c'] +elif rtconfig.CROSS_TOOL == 'keil': + src += ['startup/keil_startup_lpc5410x.s'] + +group = DefineGroup('CMSIS', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x-m0.c b/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x-m0.c new file mode 100644 index 0000000000000000000000000000000000000000..0047e0a547d85110dcdd040d962bfecb3dcbe729 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x-m0.c @@ -0,0 +1,452 @@ +//***************************************************************************** +// LPC5410x M0 Microcontroller Startup code for use with LPCXpresso IDE +// +// Version : 141022 +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2014 +// 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. +//***************************************************************************** + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) +// Declaration of external SystemInit function +extern void SystemInit(void); +#endif + +//***************************************************************************** +// +// Forward declaration of the default handlers. These are aliased. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +// +//***************************************************************************** +void ResetISR(void); +#if defined (__MULTICORE_MASTER) +void ResetISR2(void); +#endif +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +//WEAK void MemManage_Handler(void); +//WEAK void BusFault_Handler(void); +//WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +//WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// +// Forward declaration of the specific IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +// +//***************************************************************************** +// External Interrupts - Available on M0/M4 +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void UTICK_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B0_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B2_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B3_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B4_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART3_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_IRQHandler(void) ALIAS(IntDefaultHandler); +void MAILBOX_IRQHandler(void) ALIAS(IntDefaultHandler); +// External Interrupts - For M4 only +//void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +//void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler); +//void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler); +//void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler); +//void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler); +//void SPI2_IRQHandler(void) ALIAS(IntDefaultHandler); +//void SPI3_IRQHandler(void) ALIAS(IntDefaultHandler); +//void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +//void Reserved41_IRQHandler(void) ALIAS(IntDefaultHandler); +//void Reserved42_IRQHandler(void) ALIAS(IntDefaultHandler); +//void Reserved43_IRQHandler(void) ALIAS(IntDefaultHandler); +//void Reserved44_IRQHandler(void) ALIAS(IntDefaultHandler); +//***************************************************************************** +// +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +// +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); +//***************************************************************************** +// +// External declaration for the pointer to the stack top from the Linker Script +// +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif +//***************************************************************************** +// +// The vector table. +// This relies on the linker script to place at correct location in memory. +// +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + // Core Level - CM0plus + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + 0, // Reserved + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // External Interrupts - Available on M0/M4 + WDT_IRQHandler, // Watchdog + BOD_IRQHandler, // Brown Out Detect + Reserved_IRQHandler, // Reserved + DMA_IRQHandler, // DMA Controller + GINT0_IRQHandler, // GPIO Group0 Interrupt + PIN_INT0_IRQHandler, // PIO INT0 + PIN_INT1_IRQHandler, // PIO INT1 + PIN_INT2_IRQHandler, // PIO INT2 + PIN_INT3_IRQHandler, // PIO INT3 + UTICK_IRQHandler, // UTICK timer + MRT_IRQHandler, // Multi-Rate Timer + CT32B0_IRQHandler, // Counter Timer 0 + CT32B1_IRQHandler, // Counter Timer 1 + CT32B2_IRQHandler, // Counter Timer 2 + CT32B3_IRQHandler, // Counter Timer 3 + CT32B4_IRQHandler, // Counter Timer 4 + SCT0_IRQHandler, // Smart Counter Timer + UART0_IRQHandler, // UART0 + UART1_IRQHandler, // UART1 + UART2_IRQHandler, // UART2 + UART3_IRQHandler, // UART3 + I2C0_IRQHandler, // I2C0 controller + I2C1_IRQHandler, // I2C1 controller + I2C2_IRQHandler, // I2C2 controller + SPI0_IRQHandler, // SPI0 controller + SPI1_IRQHandler, // SPI1 controller + ADC_SEQA_IRQHandler, // ADC SEQA + ADC_SEQB_IRQHandler, // ADC SEQB + ADC_THCMP_IRQHandler, // ADC THCMP and OVERRUN ORed + RTC_IRQHandler, // RTC Timer + Reserved_IRQHandler, // Reserved + MAILBOX_IRQHandler, // Mailbox + + // External Interrupts - For M4 only +// GINT1_IRQHandler, // GPIO Group1 Interrupt +// PIN_INT4_IRQHandler, // PIO INT4 +// PIN_INT5_IRQHandler, // PIO INT5 +// PIN_INT6_IRQHandler, // PIO INT6 +// PIN_INT7_IRQHandler, // PIO INT7 +// SPI2_IRQHandler, // SPI2 controller +// SPI3_IRQHandler, // SPI3 controller +// 0, // Reserved +// RIT_IRQHandler, // RIT Timer +// Reserved41_IRQHandler, // Reserved +// Reserved42_IRQHandler, // Reserved +// Reserved43_IRQHandler, // Reserved +// Reserved44_IRQHandler, // Reserved + +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** + +#if defined (__MULTICORE_MASTER) +//#define cpu_ctrl 0x40000300 +//#define coproc_boot 0x40000304 +//#define set coproc_stack 0x40000308 +__attribute__ ((naked, section(".after_vectors.reset"))) +void ResetISR(void) { + asm volatile( + ".syntax unified\t\n" + ".set cpu_ctrl, 0x40000300\t\n" + ".set coproc_boot, 0x40000304\t\n" + ".set coproc_stack, 0x40000308\t\n" + "MOVS R5, #1\t\n" + "LDR R0, =0xE000ED00\t\n" + "LDR R1, [R0]\t\n" // READ CPUID register + "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier + "EORS R1,R1,R2\t\n" // XOR to see if we are C0 + "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL + "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1 + "BEQ.N cm0_boot\t\n" + "cm4_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset + "BX R0\t\n" // otherwise, we branch to boot address + "commonboot:\t\n" + "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler + "BX R0\t\n" + "cm0_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset + "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK) + "LDR R1,[R1]\t\n" + "MOV SP,R1\t\n" + "BX R0\t\n" // goto boot address + "check_master_m0:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BEQ.N commonboot\t\n" // if we get 0, that means we are masters + "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep + "check_master_m4:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BNE.N commonboot\t\n" // if we get 1, that means we are masters + "goto_sleep_pending_reset:\t\n" + "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup + // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage) + // this code should only be reached if debugger bypassed ROM or we changed master without giving + // correct start address, the only way out of this is through a debugger change of SP and PC + "sleepo:\t\n" + "WFI\t\n" // go to sleep + "B.N sleepo\t\n" + ".syntax divided\t\n" + ); +} + + +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR2(void) { + +#else +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR(void) { +#endif + + // If this is not the CM0+ core... +#if !defined (CORE_M0PLUS) + // If this is not a slave project... +#if !defined (__MULTICORE_M0SLAVE) && \ + !defined (__MULTICORE_M4SLAVE) + // Optionally enable RAM banks that may be off by default at reset +#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) + volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0; + // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set + *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4); +#endif +#endif +#endif + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + +#if !defined (__USE_LPCOPEN) +// LPCOpen init code deals with VTOR initialisation + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) { + // CMSIS : SCB->VTOR =
+ *pSCB_VTOR = (unsigned int) g_pfnVectors; + } +#endif +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) + SystemInit(); +#endif + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main(); +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void NMI_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void HardFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SVC_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void PendSV_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SysTick_Handler(void) +{ while(1) {} +} + +//***************************************************************************** +// +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +// +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void IntDefaultHandler(void) +{ while(1) {} +} diff --git a/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x.c b/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..dfc9b16b3923c0e65b538b8307af9f0b6fd9e00d --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/cr_startup_lpc5410x.c @@ -0,0 +1,482 @@ +//***************************************************************************** +// LPC5410x Microcontroller Startup code for use with LPCXpresso IDE +// +// Version : 141022 +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2014 +// 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. +//***************************************************************************** + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) +// Declaration of external SystemInit function +extern void SystemInit(void); +#endif + +//***************************************************************************** +// +// Forward declaration of the default handlers. These are aliased. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +// +//***************************************************************************** +void ResetISR(void); +#if defined (__MULTICORE_MASTER) +void ResetISR2(void); +#endif +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// +// Forward declaration of the specific IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +// +//***************************************************************************** +// External Interrupts - Available on M0/M4 +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void UTICK_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B0_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B2_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B3_IRQHandler(void) ALIAS(IntDefaultHandler); +void CT32B4_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART3_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_IRQHandler(void) ALIAS(IntDefaultHandler); +void MAILBOX_IRQHandler(void) ALIAS(IntDefaultHandler); +// External Interrupts - For M4 only +void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI3_IRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved41_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved42_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved43_IRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved44_IRQHandler(void) ALIAS(IntDefaultHandler); + +//***************************************************************************** +// +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +// +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); +//***************************************************************************** +// +// External declaration for the pointer to the stack top from the Linker Script +// +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif +//***************************************************************************** +// +// The vector table. +// This relies on the linker script to place at correct location in memory. +// +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + // Core Level - CM3 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // External Interrupts - Available on M0/M4 + WDT_IRQHandler, // Watchdog + BOD_IRQHandler, // Brown Out Detect + Reserved_IRQHandler, // Reserved + DMA_IRQHandler, // DMA Controller + GINT0_IRQHandler, // GPIO Group0 Interrupt + PIN_INT0_IRQHandler, // PIO INT0 + PIN_INT1_IRQHandler, // PIO INT1 + PIN_INT2_IRQHandler, // PIO INT2 + PIN_INT3_IRQHandler, // PIO INT3 + UTICK_IRQHandler, // UTICK timer + MRT_IRQHandler, // Multi-Rate Timer + CT32B0_IRQHandler, // Counter Timer 0 + CT32B1_IRQHandler, // Counter Timer 1 + CT32B2_IRQHandler, // Counter Timer 2 + CT32B3_IRQHandler, // Counter Timer 3 + CT32B4_IRQHandler, // Counter Timer 4 + SCT0_IRQHandler, // Smart Counter Timer + UART0_IRQHandler, // UART0 + UART1_IRQHandler, // UART1 + UART2_IRQHandler, // UART2 + UART3_IRQHandler, // UART3 + I2C0_IRQHandler, // I2C0 controller + I2C1_IRQHandler, // I2C1 controller + I2C2_IRQHandler, // I2C2 controller + SPI0_IRQHandler, // SPI0 controller + SPI1_IRQHandler, // SPI1 controller + ADC_SEQA_IRQHandler, // ADC SEQA + ADC_SEQB_IRQHandler, // ADC SEQB + ADC_THCMP_IRQHandler, // ADC THCMP and OVERRUN ORed + RTC_IRQHandler, // RTC Timer + Reserved_IRQHandler, // Reserved + MAILBOX_IRQHandler, // Mailbox + + // External Interrupts - For M4 only + GINT1_IRQHandler, // GPIO Group1 Interrupt + PIN_INT4_IRQHandler, // PIO INT4 + PIN_INT5_IRQHandler, // PIO INT5 + PIN_INT6_IRQHandler, // PIO INT6 + PIN_INT7_IRQHandler, // PIO INT7 + SPI2_IRQHandler, // SPI2 controller + SPI3_IRQHandler, // SPI3 controller + 0, // Reserved + RIT_IRQHandler, // RIT Timer + Reserved41_IRQHandler, // Reserved + Reserved42_IRQHandler, // Reserved + Reserved43_IRQHandler, // Reserved + Reserved44_IRQHandler, // Reserved + +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** + +#if defined (__MULTICORE_MASTER) +//#define cpu_ctrl 0x40000300 +//#define coproc_boot 0x40000304 +//#define set coproc_stack 0x40000308 +__attribute__ ((naked, section(".after_vectors.reset"))) +void ResetISR(void) { + asm volatile( + ".set cpu_ctrl, 0x40000300\t\n" + ".set coproc_boot, 0x40000304\t\n" + ".set coproc_stack, 0x40000308\t\n" + "MOVS R5, #1\t\n" + "LDR R0, =0xE000ED00\t\n" + "LDR R1, [R0]\t\n" // READ CPUID register + "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier + "EORS R1,R1,R2\t\n" // XOR to see if we are C0 + "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL + "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1 + "BEQ.N cm0_boot\t\n" + "cm4_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset + "BX R0\t\n" // otherwise, we branch to boot address + "commonboot:\t\n" + "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler + "BX R0\t\n" + "cm0_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset + "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK) + "LDR R1,[R1]\t\n" + "MOV SP,R1\t\n" + "BX R0\t\n" // goto boot address + "check_master_m0:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BEQ.N commonboot\t\n" // if we get 0, that means we are masters + "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep + "check_master_m4:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BNE.N commonboot\t\n" // if we get 1, that means we are masters + "goto_sleep_pending_reset:\t\n" + "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup + // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage) + // this code should only be reached if debugger bypassed ROM or we changed master without giving + // correct start address, the only way out of this is through a debugger change of SP and PC + "sleepo:\t\n" + "WFI\t\n" // go to sleep + "B.N sleepo\t\n" + ); +} + + +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR2(void) { + +#else +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR(void) { +#endif + + // If this is not the CM0+ core... +#if !defined (CORE_M0PLUS) + // If this is not a slave project... +#if !defined (__MULTICORE_M0SLAVE) && \ + !defined (__MULTICORE_M4SLAVE) + // Optionally enable RAM banks that may be off by default at reset +#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) + volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0; + // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set + *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4); +#endif +#endif +#endif + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + +#if !defined (__USE_LPCOPEN) +// LPCOpen init code deals with FP and VTOR initialisation +#if defined (__VFP_FP__) && !defined (__SOFTFP__) + /* + * Code to enable the Cortex-M4 FPU only included + * if appropriate build options have been selected. + * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + */ + // CPACR is located at address 0xE000ED88 + asm("LDR.W R0, =0xE000ED88"); + // Read CPACR + asm("LDR R1, [R0]"); + // Set bits 20-23 to enable CP10 and CP11 coprocessors + asm(" ORR R1, R1, #(0xF << 20)"); + // Write back the modified value to the CPACR + asm("STR R1, [R0]"); +#endif // (__VFP_FP__) && !(__SOFTFP__) + // ****************************** + // Check to see if we are running the code from a non-zero + // address (eg RAM, external flash), in which case we need + // to modify the VTOR register to tell the CPU that the + // vector table is located at a non-0x0 address. + + // Note that we do not use the CMSIS register access mechanism, + // as there is no guarantee that the project has been configured + // to use CMSIS. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) { + // CMSIS : SCB->VTOR =
+ *pSCB_VTOR = (unsigned int) g_pfnVectors; + } +#endif +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) + SystemInit(); +#endif + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main(); +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void NMI_Handler(void) { + while (1) { + } +} + +__attribute__ ((section(".after_vectors"))) +void HardFault_Handler(void) { + while (1) { + } +} + +__attribute__ ((section(".after_vectors"))) +void SVC_Handler(void) { + while (1) { + } +} + +__attribute__ ((section(".after_vectors"))) +void PendSV_Handler(void) { + while (1) { + } +} + +__attribute__ ((section(".after_vectors"))) +void SysTick_Handler(void) { + while (1) { + } +} + +//***************************************************************************** +// +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +// +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void IntDefaultHandler(void) { + while (1) { + } +} + diff --git a/bsp/lpc5410x/Libraries/Device/startup/crp.c b/bsp/lpc5410x/Libraries/Device/startup/crp.c new file mode 100644 index 0000000000000000000000000000000000000000..5abed58b938042fe58c2c4cbfcb83a0fddf3009a --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/crp.c @@ -0,0 +1,38 @@ +//***************************************************************************** +// crp.c +// +// Source file to create CRP word expected by LPCXpresso IDE linker +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2013 +// 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. +//***************************************************************************** + +#if defined (__CODE_RED) +#include +// Variable to store CRP value in. Will be placed automatically +// by the linker when "Enable Code Read Protect" selected. +// See crp.h header for more information +__CRP const unsigned int CRP_WORD = CRP_NO_CRP ; +#endif diff --git a/bsp/lpc5410x/Libraries/Device/startup/gcc_startup_lpc5410x.c b/bsp/lpc5410x/Libraries/Device/startup/gcc_startup_lpc5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..1cd349e94dba4ec5eba97f3b676d5c02d0f059c9 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/gcc_startup_lpc5410x.c @@ -0,0 +1,272 @@ +//***************************************************************************** +// +// Startup code for use with GNU tools. +// +//***************************************************************************** + + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +static void Reset_Handler(void); +static void Default_Handler(void); + +//***************************************************************************** +// +// External declaration for the interrupt handler used by the application. +// +//***************************************************************************** +void NMI_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void MemManage_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void BusFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void UsageFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void SVC_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void DebugMon_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler"))); +void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler"))); + +void WDT_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void BOD_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void Reserved_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void DMA_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void GINT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); + +void PIN_INT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void UTICK_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void MRT_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void CT32B0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void CT32B1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void CT32B2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void CT32B3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void CT32B4_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void SCT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void UART0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void UART1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void UART2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void UART3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void I2C0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void I2C1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void I2C2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void SPI0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void SPI1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void ADC_SEQA_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void ADC_SEQB_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void ADC_THCMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void RTC_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +//void Reserved_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void MAILBOX_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void GINT1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT4_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT5_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT6_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void PIN_INT7_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +//void Reserved_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +//void Reserved_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +//void Reserved_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void RIT_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void Reserved41_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void Reserved42_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void Reserved43_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +void Reserved44_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static unsigned long pulStack[512]; + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), + // The initial stack pointer + Reset_Handler, // Reset Handler + NMI_Handler, // NMI Handler + HardFault_Handler, // Hard Fault Handler + MemManage_Handler, // MPU Fault Handler + BusFault_Handler, // Bus Fault Handler + UsageFault_Handler, // Usage Fault Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall Handler + DebugMon_Handler, // Debug Monitor Handler + 0, // Reserved + PendSV_Handler, // PendSV Handler + SysTick_Handler, // SysTick Handler + + // External Interrupts + WDT_IRQHandler, + BOD_IRQHandler, + Reserved_IRQHandler, + DMA_IRQHandler, + GINT0_IRQHandler, + PIN_INT0_IRQHandler, + PIN_INT1_IRQHandler, + PIN_INT2_IRQHandler, + PIN_INT3_IRQHandler, + UTICK_IRQHandler, + MRT_IRQHandler, + CT32B0_IRQHandler, + CT32B1_IRQHandler, + CT32B2_IRQHandler, + CT32B3_IRQHandler, + CT32B4_IRQHandler, + SCT0_IRQHandler, + UART0_IRQHandler, + UART1_IRQHandler, + UART2_IRQHandler, + UART3_IRQHandler, + I2C0_IRQHandler, + I2C1_IRQHandler, + I2C2_IRQHandler, + SPI0_IRQHandler, + SPI1_IRQHandler, + ADC_SEQA_IRQHandler, + ADC_SEQB_IRQHandler, + ADC_THCMP_IRQHandler, + RTC_IRQHandler, + Reserved_IRQHandler, + MAILBOX_IRQHandler, + GINT1_IRQHandler, + PIN_INT4_IRQHandler, + PIN_INT5_IRQHandler, + PIN_INT6_IRQHandler, + PIN_INT7_IRQHandler, + Reserved_IRQHandler, + Reserved_IRQHandler, + Reserved_IRQHandler, + RIT_IRQHandler, + Reserved41_IRQHandler, + Reserved42_IRQHandler, + Reserved43_IRQHandler, + Reserved44_IRQHandler, +}; +//**RIT_IRQHandler *************************************************************************** +// Reserved41_IRQHandler +// TReserved42_IRQHandler he following are constructs created by the linker, indicating where the +// tReserved43_IRQHandler he "data" and "bss" segments reside in memory. The initializers for the +// fReserved44_IRQHandler or the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern unsigned long _etext; +extern unsigned long _data; +extern unsigned long _edata; +extern unsigned long _bss; +extern unsigned long _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +static void Reset_Handler(void) +{ + unsigned long *pulSrc, *pulDest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pulSrc = &_etext; + for(pulDest = &_data; pulDest < &_edata; ) + { + *pulDest++ = *pulSrc++; + } + + +#if !defined (__USE_LPCOPEN) +// LPCOpen init code deals with FP and VTOR initialisation +#if defined (__VFP_FP__) && !defined (__SOFTFP__) + /* + * Code to enable the Cortex-M4 FPU only included + * if appropriate build options have been selected. + * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + */ + // CPACR is located at address 0xE000ED88 + asm("LDR.W R0, =0xE000ED88"); + // Read CPACR + asm("LDR R1, [R0]"); + // Set bits 20-23 to enable CP10 and CP11 coprocessors + asm(" ORR R1, R1, #(0xF << 20)"); + // Write back the modified value to the CPACR + asm("STR R1, [R0]"); +#endif // (__VFP_FP__) && !(__SOFTFP__) + // ****************************** + // Check to see if we are running the code from a non-zero + // address (eg RAM, external flash), in which case we need + // to modify the VTOR register to tell the CPU that the + // vector table is located at a non-0x0 address. + + // Note that we do not use the CMSIS register access mechanism, + // as there is no guarantee that the project has been configured + // to use CMSIS. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) { + // CMSIS : SCB->VTOR =
+ *pSCB_VTOR = (unsigned int) g_pfnVectors; + } +#endif + + // + // Zero fill the bss segment. + // + __asm(" ldr r0, =_bss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + " .thumb_func\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + + // call system init. + SystemInit(); + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void Default_Handler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x-m0.s b/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x-m0.s new file mode 100644 index 0000000000000000000000000000000000000000..bc99ab5dc7d61c6cd0d646eba6843e2eb48504a3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x-m0.s @@ -0,0 +1,304 @@ +;/***************************************************************************** +; * @file: startup_LPC5410x-m0.s +; * @purpose: CMSIS Cortex-M4/M0+ Core Device Startup File +; * for the NXP LPC5410x Device Series (manually edited) +; * @version: V1.00 +; * @date: 19. October 2009 +; *---------------------------------------------------------------------------- +; * +; * Copyright (C) 2009 ARM Limited. All rights reserved. +; * +; * ARM Limited (ARM) is supplying this software for use with Cortex-Mx +; * 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. +; * +; ******************************************************************************/ + +; +; 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 + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 + DCD 0 + DCD 0 +__vector_table_0x1c + DCD 0 ; Checksum of the first 7 words + DCD 0 + DCD 0 ; Enhanced image marker, set to 0x0 for legacy boot + DCD 0 ; Pointer to enhanced boot block, set to 0x0 for legacy boot + DCD SVC_Handler + DCD 0 + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_IRQHandler ; Watchdog + DCD BOD_IRQHandler ; Brown Out Detect + DCD Reserved_IRQHandler ; Reserved + DCD DMA_IRQHandler ; DMA Controller + DCD GINT0_IRQHandler ; GPIO Group0 Interrupt + 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 UTICK_IRQHandler ; UTICK timer + DCD MRT_IRQHandler ; Multi-Rate Timer + DCD CT32B0_IRQHandler ; CT32B0 + DCD CT32B1_IRQHandler ; CT32B1 + DCD CT32B2_IRQHandler ; CT32B2 + DCD CT32B3_IRQHandler ; CT32B3 + DCD CT32B4_IRQHandler ; CT32B4 + DCD SCT0_IRQHandler ; Smart Counter Timer + DCD UART0_IRQHandler ; UART0 + DCD UART1_IRQHandler ; UART1 + DCD UART2_IRQHandler ; UART2 + DCD UART3_IRQHandler ; UART3 + DCD I2C0_IRQHandler ; I2C0 controller + DCD I2C1_IRQHandler ; I2C1 controller + DCD I2C2_IRQHandler ; I2C2 controller + DCD SPI0_IRQHandler ; SPI0 controller + DCD SPI1_IRQHandler ; SPI1 controller + DCD ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + DCD ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + DCD ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + DCD RTC_IRQHandler ; RTC Timer + DCD Reserved_IRQHandler ; Reserved + DCD MAILBOX_IRQHandler ; Mailbox + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + +#if !defined(SLAVEBOOT) + DATA +cpu_id EQU 0xE000ED00 +cpu_ctrl EQU 0x40000300 +coproc_boot EQU 0x40000304 +coproc_stack EQU 0x40000308 +rel_vals + DC32 cpu_id, cpu_ctrl, coproc_boot, coproc_stack + DC16 0xFFF, 0xC24 +#endif + + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +; Reset Handler - shared for both cores +Reset_Handler + +#if !defined(SLAVEBOOT) +; Both the M0+ and M4 core come via this shared startup code, + ; but the M0+ and M4 core have different vector tables. + ; Determine if the core executing this code is the master or + ; the slave and handle each core state individually. +shared_boot_entry + LDR r6, =rel_vals + MOVS r4, #0 ; Flag for slave core (0) + MOVS r5, #1 + + ; Determine which core (M0+ or M4) this code is running on + ; r2 = (((*cpu_id) >> 4) & 0xFFF); (M4 core == 0xC24) +get_current_core_id + LDR r0, [r6, #0] + LDR r1, [r0] ; r1 = CPU ID status + LSRS r1, r1, #4 ; Right justify 12 CPU ID bits + LDRH r2, [r6, #16] ; Mask for CPU ID bits + ANDS r2, r1, r2 ; r2 = ARM COrtex CPU ID + LDRH r3, [r6, #18] ; Mask for CPU ID bits + CMP r3, r2 ; Core ID matches M4 identifier + BNE get_master_status + MOV r4, r5 ; Set flag for master core (1) + + ; Determine if M4 core is the master or slave + ; r3 = ((*cpu_ctrl) & 1); (0 == m0+, 1 == M4) +get_master_status + LDR r0, [r6, #4] + LDR r3, [r0] ; r3 = SYSCON co-processor CPU control status + ANDS r3, r3, r5 ; r3 = (Bit 0: 1 = M4 is master, 0 = M4 is slave) + + ; Select boot based on selected master core and core ID +select_boot + EORS r3, r3, r4 ; r4 = (Bit 0: 0 = master, 1 = slave) + BNE slave_boot + B normal_boot + + ; Slave boot +slave_boot + LDR r0, [r6, #8] + LDR r2, [r0] ; r1 = SYSCON co-processor boot address + CMP r2, #0 ; Slave boot address = 0 (not set up)? + BEQ cpu_sleep + LDR r0, [r6, #12] + LDR r1, [r0] ; r5 = SYSCON co-processor stack address + MOV sp, r1 ; Update slave CPU stack pointer + ; Be sure to update VTOR for the slave MCU to point to the + ; slave vector table in boot memory + BX r2 ; Jump to slave boot address + + ; Slave isn't yet setup for system boot from the master + ; so sleep until the master sets it up and then reboots it +cpu_sleep + MOV sp, r5 ; Will force exception if something happens +cpu_sleep_wfi + WFI ; Sleep forever until master reboots + B cpu_sleep_wfi +#endif ; defined(SLAVEBOOT) + + ; Normal boot for master/slave +normal_boot + LDR r0, =SystemInit + BLX r0 + LDR r0, =__iar_program_start + BX r0 + +; For cores with SystemInit() or __iar_program_start(), the code will sleep the MCU + PUBWEAK SystemInit + SECTION .text:CODE:REORDER:NOROOT(1) +SystemInit + BX LR + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK Reserved_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +Reserved_IRQHandler + B . + + PUBWEAK WDT_IRQHandler ; Watchdog + PUBWEAK BOD_IRQHandler ; Brown Out Detect + PUBWEAK DMA_IRQHandler ; DMA Controller + PUBWEAK GINT0_IRQHandler ; GPIO Group0 Interrupt + PUBWEAK PIN_INT0_IRQHandler ; PIO INT0 + PUBWEAK PIN_INT1_IRQHandler ; PIO INT1 + PUBWEAK PIN_INT2_IRQHandler ; PIO INT2 + PUBWEAK PIN_INT3_IRQHandler ; PIO INT3 + PUBWEAK UTICK_IRQHandler ; UTICK timer + PUBWEAK MRT_IRQHandler ; Multi-Rate Timer + PUBWEAK CT32B0_IRQHandler ; CT32B0 + PUBWEAK CT32B1_IRQHandler ; CT32B1 + PUBWEAK CT32B2_IRQHandler ; CT32B2 + PUBWEAK CT32B3_IRQHandler ; CT32B3 + PUBWEAK CT32B4_IRQHandler ; CT32B4 + PUBWEAK UART0_IRQHandler ; UART0 + PUBWEAK SCT0_IRQHandler ; Smart Counter Timer + PUBWEAK UART1_IRQHandler ; UART1 + PUBWEAK UART2_IRQHandler ; UART2 + PUBWEAK UART3_IRQHandler ; UART3 + PUBWEAK I2C0_IRQHandler ; I2C0 controller + PUBWEAK I2C1_IRQHandler ; I2C1 controller + PUBWEAK I2C2_IRQHandler ; I2C2 controller + PUBWEAK SPI0_IRQHandler ; SPI0 controller + PUBWEAK SPI1_IRQHandler ; SPI1 controller + PUBWEAK ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + PUBWEAK ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + PUBWEAK ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + PUBWEAK RTC_IRQHandler ; RTC Timer + PUBWEAK MAILBOX_IRQHandler ; Mailbox + +WDT_IRQHandler ; Watchdog +BOD_IRQHandler ; Brown Out Detect +DMA_IRQHandler ; DMA Controller +GINT0_IRQHandler ; GPIO Group0 Interrupt +PIN_INT0_IRQHandler ; PIO INT0 +PIN_INT1_IRQHandler ; PIO INT1 +PIN_INT2_IRQHandler ; PIO INT2 +PIN_INT3_IRQHandler ; PIO INT3 +UTICK_IRQHandler ; UTICK timer +MRT_IRQHandler ; Multi-Rate Timer +CT32B0_IRQHandler ; CT32B0 +CT32B1_IRQHandler ; CT32B1 +CT32B2_IRQHandler ; CT32B2 +CT32B3_IRQHandler ; CT32B3 +CT32B4_IRQHandler ; CT32B4 +UART0_IRQHandler ; UART0 +SCT0_IRQHandler ; Smart Counter Timer +UART1_IRQHandler ; UART1 +UART2_IRQHandler ; UART2 +UART3_IRQHandler ; UART3 +I2C0_IRQHandler ; I2C0 controller +I2C1_IRQHandler ; I2C1 controller +I2C2_IRQHandler ; I2C2 controller +SPI0_IRQHandler ; SPI0 controller +SPI1_IRQHandler ; SPI1 controller +ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt +ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt +ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed +RTC_IRQHandler ; RTC Timer +MAILBOX_IRQHandler ; Mailbox + +Default_Handler: + B . + + END diff --git a/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x.s b/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x.s new file mode 100644 index 0000000000000000000000000000000000000000..f78911b62a0066f532113058b4ecc01db4614b9c --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/iar_startup_lpc5410x.s @@ -0,0 +1,356 @@ +;/***************************************************************************** +; * @file: startup_LPC5410x.s +; * @purpose: CMSIS Cortex-M4/M0+ Core Device Startup File +; * for the NXP LPC5410x Device Series (manually edited) +; * @version: V1.00 +; * @date: 19. October 2009 +; *---------------------------------------------------------------------------- +; * +; * Copyright (C) 2009 ARM Limited. All rights reserved. +; * +; * ARM Limited (ARM) is supplying this software for use with Cortex-Mx +; * 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. +; * +; ******************************************************************************/ + +; +; 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 + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler + DCD HardFault_Handler + DCD MemManage_Handler + DCD BusFault_Handler + DCD UsageFault_Handler +__vector_table_0x1c + DCD 0 ; Checksum of the first 7 words + DCD 0 + DCD 0 ; Enhanced image marker, set to 0x0 for legacy boot + DCD 0 ; Pointer to enhanced boot block, set to 0x0 for legacy boot + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_IRQHandler ; Watchdog + DCD BOD_IRQHandler ; Brown Out Detect + DCD Reserved_IRQHandler ; Reserved + DCD DMA_IRQHandler ; DMA Controller + DCD GINT0_IRQHandler ; GPIO Group0 Interrupt + 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 UTICK_IRQHandler ; UTICK timer + DCD MRT_IRQHandler ; Multi-Rate Timer + DCD CT32B0_IRQHandler ; CT32B0 + DCD CT32B1_IRQHandler ; CT32B1 + DCD CT32B2_IRQHandler ; CT32B2 + DCD CT32B3_IRQHandler ; CT32B3 + DCD CT32B4_IRQHandler ; CT32B4 + DCD SCT0_IRQHandler ; Smart Counter Timer + DCD UART0_IRQHandler ; UART0 + DCD UART1_IRQHandler ; UART1 + DCD UART2_IRQHandler ; UART2 + DCD UART3_IRQHandler ; UART3 + DCD I2C0_IRQHandler ; I2C0 controller + DCD I2C1_IRQHandler ; I2C1 controller + DCD I2C2_IRQHandler ; I2C2 controller + DCD SPI0_IRQHandler ; SPI0 controller + DCD SPI1_IRQHandler ; SPI1 controller + DCD ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + DCD ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + DCD ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + DCD RTC_IRQHandler ; RTC Timer + DCD Reserved_IRQHandler ; Reserved + DCD MAILBOX_IRQHandler ; Mailbox + DCD GINT1_IRQHandler ; GPIO Group1 Interrupt + DCD PIN_INT4_IRQHandler ; PIO INT4 + DCD PIN_INT5_IRQHandler ; PIO INT5 + DCD PIN_INT6_IRQHandler ; PIO INT6 + DCD PIN_INT7_IRQHandler ; PIO INT7 + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD RIT_IRQHandler ; RITimer + DCD Reserved41_IRQHandler ; Reserved + DCD Reserved42_IRQHandler ; Reserved + DCD Reserved43_IRQHandler ; Reserved + DCD Reserved44_IRQHandler ; Reserved +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + +#if !defined(SLAVEBOOT) + DATA +cpu_id EQU 0xE000ED00 +cpu_ctrl EQU 0x40000300 +coproc_boot EQU 0x40000304 +coproc_stack EQU 0x40000308 +rel_vals + DC32 cpu_id, cpu_ctrl, coproc_boot, coproc_stack + DC16 0xFFF, 0xC24 +#endif + + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +; Reset Handler - shared for both cores +Reset_Handler + +#if !defined(SLAVEBOOT) +; Both the M0+ and M4 core come via this shared startup code, + ; but the M0+ and M4 core have different vector tables. + ; Determine if the core executing this code is the master or + ; the slave and handle each core state individually. +shared_boot_entry + LDR r6, =rel_vals + MOVS r4, #0 ; Flag for slave core (0) + MOVS r5, #1 + + ; Determine which core (M0+ or M4) this code is running on + ; r2 = (((*cpu_id) >> 4) & 0xFFF); (M4 core == 0xC24) +get_current_core_id + LDR r0, [r6, #0] + LDR r1, [r0] ; r1 = CPU ID status + LSRS r1, r1, #4 ; Right justify 12 CPU ID bits + LDRH r2, [r6, #16] ; Mask for CPU ID bits + ANDS r2, r1, r2 ; r2 = ARM COrtex CPU ID + LDRH r3, [r6, #18] ; Mask for CPU ID bits + CMP r3, r2 ; Core ID matches M4 identifier + BNE get_master_status + MOV r4, r5 ; Set flag for master core (1) + + ; Determine if M4 core is the master or slave + ; r3 = ((*cpu_ctrl) & 1); (0 == m0+, 1 == M4) +get_master_status + LDR r0, [r6, #4] + LDR r3, [r0] ; r3 = SYSCON co-processor CPU control status + ANDS r3, r3, r5 ; r3 = (Bit 0: 1 = M4 is master, 0 = M4 is slave) + + ; Select boot based on selected master core and core ID +select_boot + EORS r3, r3, r4 ; r4 = (Bit 0: 0 = master, 1 = slave) + BNE slave_boot + B normal_boot + + ; Slave boot +slave_boot + LDR r0, [r6, #8] + LDR r2, [r0] ; r1 = SYSCON co-processor boot address + CMP r2, #0 ; Slave boot address = 0 (not set up)? + BEQ cpu_sleep + LDR r0, [r6, #12] + LDR r1, [r0] ; r5 = SYSCON co-processor stack address + MOV sp, r1 ; Update slave CPU stack pointer + ; Be sure to update VTOR for the slave MCU to point to the + ; slave vector table in boot memory + BX r2 ; Jump to slave boot address + + ; Slave isn't yet setup for system boot from the master + ; so sleep until the master sets it up and then reboots it +cpu_sleep + MOV sp, r5 ; Will force exception if something happens +cpu_sleep_wfi + WFI ; Sleep forever until master reboots + B cpu_sleep_wfi +#endif ; defined(SLAVEBOOT) + + ; Normal boot for master/slave +normal_boot + LDR r0, =SystemInit + BLX r0 + LDR r0, =__iar_program_start + BX r0 + +; For cores with SystemInit() or __iar_program_start(), the code will sleep the MCU + PUBWEAK SystemInit + SECTION .text:CODE:REORDER:NOROOT(1) +SystemInit + BX LR + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK Reserved_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +Reserved_IRQHandler + B . + + PUBWEAK WDT_IRQHandler ; Watchdog + PUBWEAK BOD_IRQHandler ; Brown Out Detect + PUBWEAK DMA_IRQHandler ; DMA Controller + PUBWEAK GINT0_IRQHandler ; GPIO Group0 Interrupt + PUBWEAK PIN_INT0_IRQHandler ; PIO INT0 + PUBWEAK PIN_INT1_IRQHandler ; PIO INT1 + PUBWEAK PIN_INT2_IRQHandler ; PIO INT2 + PUBWEAK PIN_INT3_IRQHandler ; PIO INT3 + PUBWEAK UTICK_IRQHandler ; UTICK timer + PUBWEAK MRT_IRQHandler ; Multi-Rate Timer + PUBWEAK CT32B0_IRQHandler ; CT32B0 + PUBWEAK CT32B1_IRQHandler ; CT32B1 + PUBWEAK CT32B2_IRQHandler ; CT32B2 + PUBWEAK CT32B3_IRQHandler ; CT32B3 + PUBWEAK CT32B4_IRQHandler ; CT32B4 + PUBWEAK UART0_IRQHandler ; UART0 + PUBWEAK SCT0_IRQHandler ; Smart Counter Timer + PUBWEAK UART1_IRQHandler ; UART1 + PUBWEAK UART2_IRQHandler ; UART2 + PUBWEAK UART3_IRQHandler ; UART3 + PUBWEAK I2C0_IRQHandler ; I2C0 controller + PUBWEAK I2C1_IRQHandler ; I2C1 controller + PUBWEAK I2C2_IRQHandler ; I2C2 controller + PUBWEAK SPI0_IRQHandler ; SPI0 controller + PUBWEAK SPI1_IRQHandler ; SPI1 controller + PUBWEAK ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + PUBWEAK ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + PUBWEAK ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + PUBWEAK RTC_IRQHandler ; RTC Timer + PUBWEAK MAILBOX_IRQHandler ; Mailbox + PUBWEAK GINT1_IRQHandler ; GPIO Group1 Interrupt + PUBWEAK PIN_INT4_IRQHandler ; PIO INT4 + PUBWEAK PIN_INT5_IRQHandler ; PIO INT5 + PUBWEAK PIN_INT6_IRQHandler ; PIO INT6 + PUBWEAK PIN_INT7_IRQHandler ; PIO INT7 + PUBWEAK RIT_IRQHandler ; RITimer + PUBWEAK Reserved41_IRQHandler ; Reserved + PUBWEAK Reserved42_IRQHandler ; Reserved + PUBWEAK Reserved43_IRQHandler ; Reserved + PUBWEAK Reserved44_IRQHandler ; Reserved + +WDT_IRQHandler ; Watchdog +BOD_IRQHandler ; Brown Out Detect +DMA_IRQHandler ; DMA Controller +GINT0_IRQHandler ; GPIO Group0 Interrupt +PIN_INT0_IRQHandler ; PIO INT0 +PIN_INT1_IRQHandler ; PIO INT1 +PIN_INT2_IRQHandler ; PIO INT2 +PIN_INT3_IRQHandler ; PIO INT3 +UTICK_IRQHandler ; UTICK timer +MRT_IRQHandler ; Multi-Rate Timer +CT32B0_IRQHandler ; CT32B0 +CT32B1_IRQHandler ; CT32B1 +CT32B2_IRQHandler ; CT32B2 +CT32B3_IRQHandler ; CT32B3 +CT32B4_IRQHandler ; CT32B4 +UART0_IRQHandler ; UART0 +SCT0_IRQHandler ; Smart Counter Timer +UART1_IRQHandler ; UART1 +UART2_IRQHandler ; UART2 +UART3_IRQHandler ; UART3 +I2C0_IRQHandler ; I2C0 controller +I2C1_IRQHandler ; I2C1 controller +I2C2_IRQHandler ; I2C2 controller +SPI0_IRQHandler ; SPI0 controller +SPI1_IRQHandler ; SPI1 controller +ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt +ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt +ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed +RTC_IRQHandler ; RTC Timer +MAILBOX_IRQHandler ; Mailbox +GINT1_IRQHandler ; GPIO Group1 Interrupt +PIN_INT4_IRQHandler ; PIO INT4 +PIN_INT5_IRQHandler ; PIO INT5 +PIN_INT6_IRQHandler ; PIO INT6 +PIN_INT7_IRQHandler ; PIO INT7 +RIT_IRQHandler ; RITimer +Reserved41_IRQHandler ; Reserved +Reserved42_IRQHandler ; Reserved +Reserved43_IRQHandler ; Reserved +Reserved44_IRQHandler ; Reserved + +Default_Handler: + B . + + END diff --git a/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x-m0.s b/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x-m0.s new file mode 100644 index 0000000000000000000000000000000000000000..2b09d3340fbd562424d923344fc4d23ec2baf255 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x-m0.s @@ -0,0 +1,338 @@ +;/* +; * @brief LPC5410x M0 core startup code for Keil +; * +; * @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. +; */ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000200 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +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 + DCD 0 + DCD 0 +__vector_table_0x1c + DCD 0 ; Checksum of the first 7 words + DCD 0 + DCD 0 ; Enhanced image marker, set to 0x0 for legacy boot + DCD 0 ; Pointer to enhanced boot block, set to 0x0 for legacy boot + DCD SVC_Handler ; SVCall Handler + DCD 0 + DCD 0 + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WDT_IRQHandler ; Watchdog + DCD BOD_IRQHandler ; Brown Out Detect + DCD Reserved_IRQHandler ; Reserved + DCD DMA_IRQHandler ; DMA Controller + DCD GINT0_IRQHandler ; GPIO Group0 Interrupt + 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 UTICK_IRQHandler ; UTICK timer + DCD MRT_IRQHandler ; Multi-Rate Timer + DCD CT32B0_IRQHandler ; CT32B0 + DCD CT32B1_IRQHandler ; CT32B1 + DCD CT32B2_IRQHandler ; CT32B2 + DCD CT32B3_IRQHandler ; CT32B3 + DCD CT32B4_IRQHandler ; CT32B4 + DCD SCT0_IRQHandler ; Smart Counter Timer + DCD UART0_IRQHandler ; UART0 + DCD UART1_IRQHandler ; UART1 + DCD UART2_IRQHandler ; UART2 + DCD UART3_IRQHandler ; UART3 + DCD I2C0_IRQHandler ; I2C0 controller + DCD I2C1_IRQHandler ; I2C1 controller + DCD I2C2_IRQHandler ; I2C2 controller + DCD SPI0_IRQHandler ; SPI0 controller + DCD SPI1_IRQHandler ; SPI1 controller + DCD ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + DCD ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + DCD ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + DCD RTC_IRQHandler ; RTC Timer + DCD Reserved_IRQHandler ; Reserved + DCD MAILBOX_IRQHandler ; Mailbox + +;// Code Read Protection level (CRP) +;// CRP_Level: +;// <0xFFFFFFFF=> Disabled +;// <0x4E697370=> NO_ISP +;// <0x12345678=> CRP1 +;// <0x87654321=> CRP2 +;// <0x43218765=> CRP3 (Are you sure?) +;// +CRP_Level EQU 0xFFFFFFFF + + IF :LNOT::DEF:NO_CRP + AREA |.ARM.__at_0x02FC|, CODE, READONLY +CRP_Key DCD 0xFFFFFFFF + ENDIF + + AREA |.text|, CODE, READONLY + +cpu_id EQU 0xE000ED00 +cpu_ctrl EQU 0x40000300 +coproc_boot EQU 0x40000304 +coproc_stack EQU 0x40000308 + +rel_vals + DCD cpu_id, cpu_ctrl, coproc_boot, coproc_stack + DCW 0xFFF, 0xC24 + +; Reset Handler - shared for both cores +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + EXPORT SystemInit [WEAK] + IMPORT __main + + IF :LNOT::DEF:SLAVEBOOT + ; Both the M0+ and M4 core come via this shared startup code, + ; but the M0+ and M4 core have different vector tables. + ; Determine if the core executing this code is the master or + ; the slave and handle each core state individually. +shared_boot_entry + LDR r6, =rel_vals + MOVS r4, #0 ; Flag for slave core (0) + MOVS r5, #1 + + ; Determine which core (M0+ or M4) this code is running on + ; r2 = (((*cpu_id) >> 4) & 0xFFF); (M4 core == 0xC24) +get_current_core_id + LDR r0, [r6, #0] + LDR r1, [r0] ; r1 = CPU ID status + LSRS r1, r1, #4 ; Right justify 12 CPU ID bits + LDRH r2, [r6, #16] ; Mask for CPU ID bits + ANDS r2, r1, r2 ; r2 = ARM COrtex CPU ID + LDRH r3, [r6, #18] ; Mask for CPU ID bits + CMP r3, r2 ; Core ID matches M4 identifier + BNE get_master_status + MOV r4, r5 ; Set flag for master core (1) + + ; Determine if M4 core is the master or slave + ; r3 = ((*cpu_ctrl) & 1); (0 == m0+, 1 == M4) +get_master_status + LDR r0, [r6, #4] + LDR r3, [r0] ; r3 = SYSCON co-processor CPU control status + ANDS r3, r3, r5 ; r3 = (Bit 0: 1 = M4 is master, 0 = M4 is slave) + + ; Select boot based on selected master core and core ID +select_boot + EORS r3, r3, r4 ; r4 = (Bit 0: 0 = master, 1 = slave) + BNE slave_boot + B normal_boot + + ; Slave boot +slave_boot + LDR r0, [r6, #8] + LDR r2, [r0] ; r1 = SYSCON co-processor boot address + CMP r2, #0 ; Slave boot address = 0 (not set up)? + BEQ cpu_sleep + LDR r0, [r6, #12] + LDR r1, [r0] ; r5 = SYSCON co-processor stack address + MOV sp, r1 ; Update slave CPU stack pointer + ; Be sure to update VTOR for the slave MCU to point to the + ; slave vector table in boot memory + BX r2 ; Jump to slave boot address + + ; Slave isn't yet setup for system boot from the master + ; so sleep until the master sets it up and then reboots it +cpu_sleep + MOV sp, r5 ; Will force exception if something happens +cpu_sleep_wfi + WFI ; Sleep forever until master reboots + B cpu_sleep_wfi + ENDIF + + ; Normal boot for master/slave +normal_boot + LDR r0, =SystemInit + BLX r0 + LDR r0, =__main + BX r0 + ENDP + +; For cores with SystemInit() or __main(), the code will sleep the MCU +SystemInit PROC + EXPORT SystemInit [WEAK] + BX lr + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) +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 WDT_IRQHandler [WEAK] ; Watchdog + EXPORT BOD_IRQHandler [WEAK] ; Brown Out Detect + EXPORT DMA_IRQHandler [WEAK] ; DMA Controller + EXPORT GINT0_IRQHandler [WEAK] ; GPIO Group0 Interrupt + EXPORT PIN_INT0_IRQHandler [WEAK] ; PIO INT0 + EXPORT PIN_INT1_IRQHandler [WEAK] ; PIO INT1 + EXPORT PIN_INT2_IRQHandler [WEAK] ; PIO INT2 + EXPORT PIN_INT3_IRQHandler [WEAK] ; PIO INT3 + EXPORT UTICK_IRQHandler [WEAK] ; UTICK timer + EXPORT MRT_IRQHandler [WEAK] ; Multi-Rate Timer + EXPORT CT32B0_IRQHandler [WEAK] ; CT32B0 + EXPORT CT32B1_IRQHandler [WEAK] ; CT32B1 + EXPORT CT32B2_IRQHandler [WEAK] ; CT32B2 + EXPORT CT32B3_IRQHandler [WEAK] ; CT32B3 + EXPORT CT32B4_IRQHandler [WEAK] ; CT32B4 + EXPORT UART0_IRQHandler [WEAK] ; UART0 + EXPORT SCT0_IRQHandler [WEAK] ; Smart Counter Timer + EXPORT UART1_IRQHandler [WEAK] ; UART1 + EXPORT UART2_IRQHandler [WEAK] ; UART2 + EXPORT UART3_IRQHandler [WEAK] ; UART3 + EXPORT I2C0_IRQHandler [WEAK] ; I2C0 controller + EXPORT I2C1_IRQHandler [WEAK] ; I2C1 controller + EXPORT I2C2_IRQHandler [WEAK] ; I2C2 controller + EXPORT SPI0_IRQHandler [WEAK] ; SPI0 controller + EXPORT SPI1_IRQHandler [WEAK] ; SPI1 controller + EXPORT ADC_SEQA_IRQHandler [WEAK] ; ADC0 A sequence (A/D Converter) interrupt + EXPORT ADC_SEQB_IRQHandler [WEAK] ; ADC0 B sequence (A/D Converter) interrupt + EXPORT ADC_THCMP_IRQHandler [WEAK] ; ADC THCMP and OVERRUN ORed + EXPORT RTC_IRQHandler [WEAK] ; RTC Timer + EXPORT MAILBOX_IRQHandler [WEAK] ; Mailbox + EXPORT Reserved_IRQHandler [WEAK] ; Reserved + +WDT_IRQHandler ; Watchdog +BOD_IRQHandler ; Brown Out Detect +DMA_IRQHandler ; DMA Controller +GINT0_IRQHandler ; GPIO Group0 Interrupt +PIN_INT0_IRQHandler ; PIO INT0 +PIN_INT1_IRQHandler ; PIO INT1 +PIN_INT2_IRQHandler ; PIO INT2 +PIN_INT3_IRQHandler ; PIO INT3 +UTICK_IRQHandler ; UTICK timer +MRT_IRQHandler ; Multi-Rate Timer +CT32B0_IRQHandler ; CT32B0 +CT32B1_IRQHandler ; CT32B1 +CT32B2_IRQHandler ; CT32B2 +CT32B3_IRQHandler ; CT32B3 +CT32B4_IRQHandler ; CT32B4 +UART0_IRQHandler ; UART0 +SCT0_IRQHandler ; Smart Counter Timer +UART1_IRQHandler ; UART1 +UART2_IRQHandler ; UART2 +UART3_IRQHandler ; UART3 +I2C0_IRQHandler ; I2C0 controller +I2C1_IRQHandler ; I2C1 controller +I2C2_IRQHandler ; I2C2 controller +SPI0_IRQHandler ; SPI0 controller +SPI1_IRQHandler ; SPI1 controller +ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt +ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt +ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed +RTC_IRQHandler ; RTC Timer +MAILBOX_IRQHandler ; Mailbox +Reserved_IRQHandler ; Reserved + + 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 diff --git a/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x.s b/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x.s new file mode 100644 index 0000000000000000000000000000000000000000..d6a37ceb4a71bc50b182f7b7d28ad06c840b8758 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/keil_startup_lpc5410x.s @@ -0,0 +1,388 @@ +;/* +; * @brief LPC5410x startup code for Keil +; * +; * @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. +; */ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000200 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000100 + + 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 + DCD HardFault_Handler + DCD MemManage_Handler + DCD BusFault_Handler + DCD UsageFault_Handler +__vector_table_0x1c + DCD 0 ; Checksum of the first 7 words + DCD 0 + DCD 0 ; Enhanced image marker, set to 0x0 for legacy boot + DCD 0 ; Pointer to enhanced boot block, set to 0x0 for legacy boot + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_IRQHandler ; Watchdog + DCD BOD_IRQHandler ; Brown Out Detect + DCD Reserved_IRQHandler ; Reserved + DCD DMA_IRQHandler ; DMA Controller + DCD GINT0_IRQHandler ; GPIO Group0 Interrupt + 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 UTICK_IRQHandler ; UTICK timer + DCD MRT_IRQHandler ; Multi-Rate Timer + DCD CT32B0_IRQHandler ; CT32B0 + DCD CT32B1_IRQHandler ; CT32B1 + DCD CT32B2_IRQHandler ; CT32B2 + DCD CT32B3_IRQHandler ; CT32B3 + DCD CT32B4_IRQHandler ; CT32B4 + DCD SCT0_IRQHandler ; Smart Counter Timer + DCD UART0_IRQHandler ; UART0 + DCD UART1_IRQHandler ; UART1 + DCD UART2_IRQHandler ; UART2 + DCD UART3_IRQHandler ; UART3 + DCD I2C0_IRQHandler ; I2C0 controller + DCD I2C1_IRQHandler ; I2C1 controller + DCD I2C2_IRQHandler ; I2C2 controller + DCD SPI0_IRQHandler ; SPI0 controller + DCD SPI1_IRQHandler ; SPI1 controller + DCD ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt + DCD ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt + DCD ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed + DCD RTC_IRQHandler ; RTC Timer + DCD Reserved_IRQHandler ; Reserved + DCD MAILBOX_IRQHandler ; Mailbox + DCD GINT1_IRQHandler ; GPIO Group1 Interrupt + DCD PIN_INT4_IRQHandler ; PIO INT4 + DCD PIN_INT5_IRQHandler ; PIO INT5 + DCD PIN_INT6_IRQHandler ; PIO INT6 + DCD PIN_INT7_IRQHandler ; PIO INT7 + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD RIT_IRQHandler ; RITimer + DCD Reserved41_IRQHandler ; Reserved + DCD Reserved42_IRQHandler ; Reserved + DCD Reserved43_IRQHandler ; Reserved + DCD Reserved44_IRQHandler ; Reserved + +;// Code Read Protection level (CRP) +;// CRP_Level: +;// <0xFFFFFFFF=> Disabled +;// <0x4E697370=> NO_ISP +;// <0x12345678=> CRP1 +;// <0x87654321=> CRP2 +;// <0x43218765=> CRP3 (Are you sure?) +;// +;CRP_Level EQU 0xFFFFFFFF + + ;IF :LNOT::DEF:NO_CRP + ;AREA |.ARM.__at_0x02FC|, CODE, READONLY +;CRP_Key DCD 0xFFFFFFFF + ;ENDIF + + AREA |.text|, CODE, READONLY + +;cpu_id EQU 0xE000ED00 +;cpu_ctrl EQU 0x40000300 +;coproc_boot EQU 0x40000304 +;coproc_stack EQU 0x40000308 + +;rel_vals + ;DCD cpu_id, cpu_ctrl, coproc_boot, coproc_stack + ;DCW 0xFFF, 0xC24 + +; Reset Handler - shared for both cores +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + EXPORT SystemInit [WEAK] + IMPORT __main + + ;IF :LNOT::DEF:SLAVEBOOT + ;Both the M0+ and M4 core come via this shared startup code, + ;but the M0+ and M4 core have different vector tables. + ;Determine if the core executing this code is the master or + ;the slave and handle each core state individually. +;shared_boot_entry + ;LDR r6, =rel_vals + ;MOVS r4, #0 ; Flag for slave core (0) + ;MOVS r5, #1 + + ;; Determine which core (M0+ or M4) this code is running on + ;; r2 = (((*cpu_id) >> 4) & 0xFFF); (M4 core == 0xC24) +;get_current_core_id + ;LDR r0, [r6, #0] + ;LDR r1, [r0] ; r1 = CPU ID status + ;LSRS r1, r1, #4 ; Right justify 12 CPU ID bits + ;LDRH r2, [r6, #16] ; Mask for CPU ID bits + ;ANDS r2, r1, r2 ; r2 = ARM COrtex CPU ID + ;LDRH r3, [r6, #18] ; Mask for CPU ID bits + ;CMP r3, r2 ; Core ID matches M4 identifier + ;BNE get_master_status + ;MOV r4, r5 ; Set flag for master core (1) + + ;; Determine if M4 core is the master or slave + ;; r3 = ((*cpu_ctrl) & 1); (0 == m0+, 1 == M4) +;get_master_status + ;LDR r0, [r6, #4] + ;LDR r3, [r0] ; r3 = SYSCON co-processor CPU control status + ;ANDS r3, r3, r5 ; r3 = (Bit 0: 1 = M4 is master, 0 = M4 is slave) + + ;; Select boot based on selected master core and core ID +;select_boot + ;EORS r3, r3, r4 ; r4 = (Bit 0: 0 = master, 1 = slave) + ;BNE slave_boot + ;B normal_boot + + ;; Slave boot +;slave_boot + ;LDR r0, [r6, #8] + ;LDR r2, [r0] ; r1 = SYSCON co-processor boot address + ;CMP r2, #0 ; Slave boot address = 0 (not set up)? + ;BEQ cpu_sleep + ;LDR r0, [r6, #12] + ;LDR r1, [r0] ; r5 = SYSCON co-processor stack address + ;MOV sp, r1 ; Update slave CPU stack pointer + ;; Be sure to update VTOR for the slave MCU to point to the + ;; slave vector table in boot memory + ;BX r2 ; Jump to slave boot address + + ;; Slave isn't yet setup for system boot from the master + ;; so sleep until the master sets it up and then reboots it +;cpu_sleep + ;MOV sp, r5 ; Will force exception if something happens +;cpu_sleep_wfi + ;WFI ; Sleep forever until master reboots + ;B cpu_sleep_wfi + ;ENDIF + + ; Normal boot for master/slave +;normal_boot + LDR r0, =SystemInit + BLX r0 + LDR r0, =__main + BX r0 + ENDP + +; For cores with SystemInit() or __main(), the code will sleep the MCU +SystemInit PROC + EXPORT SystemInit [WEAK] + BX lr + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler PROC + EXPORT DebugMon_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 WDT_IRQHandler [WEAK] ; Watchdog + EXPORT BOD_IRQHandler [WEAK] ; Brown Out Detect + EXPORT DMA_IRQHandler [WEAK] ; DMA Controller + EXPORT GINT0_IRQHandler [WEAK] ; GPIO Group0 Interrupt + EXPORT PIN_INT0_IRQHandler [WEAK] ; PIO INT0 + EXPORT PIN_INT1_IRQHandler [WEAK] ; PIO INT1 + EXPORT PIN_INT2_IRQHandler [WEAK] ; PIO INT2 + EXPORT PIN_INT3_IRQHandler [WEAK] ; PIO INT3 + EXPORT UTICK_IRQHandler [WEAK] ; UTICK timer + EXPORT MRT_IRQHandler [WEAK] ; Multi-Rate Timer + EXPORT CT32B0_IRQHandler [WEAK] ; CT32B0 + EXPORT CT32B1_IRQHandler [WEAK] ; CT32B1 + EXPORT CT32B2_IRQHandler [WEAK] ; CT32B2 + EXPORT CT32B3_IRQHandler [WEAK] ; CT32B3 + EXPORT CT32B4_IRQHandler [WEAK] ; CT32B4 + EXPORT UART0_IRQHandler [WEAK] ; UART0 + EXPORT SCT0_IRQHandler [WEAK] ; Smart Counter Timer + EXPORT UART1_IRQHandler [WEAK] ; UART1 + EXPORT UART2_IRQHandler [WEAK] ; UART2 + EXPORT UART3_IRQHandler [WEAK] ; UART3 + EXPORT I2C0_IRQHandler [WEAK] ; I2C0 controller + EXPORT I2C1_IRQHandler [WEAK] ; I2C1 controller + EXPORT I2C2_IRQHandler [WEAK] ; I2C2 controller + EXPORT SPI0_IRQHandler [WEAK] ; SPI0 controller + EXPORT SPI1_IRQHandler [WEAK] ; SPI1 controller + EXPORT ADC_SEQA_IRQHandler [WEAK] ; ADC0 A sequence (A/D Converter) interrupt + EXPORT ADC_SEQB_IRQHandler [WEAK] ; ADC0 B sequence (A/D Converter) interrupt + EXPORT ADC_THCMP_IRQHandler [WEAK] ; ADC THCMP and OVERRUN ORed + EXPORT RTC_IRQHandler [WEAK] ; RTC Timer + EXPORT MAILBOX_IRQHandler [WEAK] ; Mailbox + EXPORT GINT1_IRQHandler [WEAK] ; GPIO Group1 Interrupt + EXPORT PIN_INT4_IRQHandler [WEAK] ; PIO INT4 + EXPORT PIN_INT5_IRQHandler [WEAK] ; PIO INT5 + EXPORT PIN_INT6_IRQHandler [WEAK] ; PIO INT6 + EXPORT PIN_INT7_IRQHandler [WEAK] ; PIO INT7 + EXPORT RIT_IRQHandler [WEAK] ; RITimer + EXPORT Reserved41_IRQHandler [WEAK] ; Reserved + EXPORT Reserved42_IRQHandler [WEAK] ; Reserved + EXPORT Reserved43_IRQHandler [WEAK] ; Reserved + EXPORT Reserved44_IRQHandler [WEAK] ; Reserved + EXPORT Reserved_IRQHandler [WEAK] ; Reserved + +WDT_IRQHandler ; Watchdog +BOD_IRQHandler ; Brown Out Detect +DMA_IRQHandler ; DMA Controller +GINT0_IRQHandler ; GPIO Group0 Interrupt +PIN_INT0_IRQHandler ; PIO INT0 +PIN_INT1_IRQHandler ; PIO INT1 +PIN_INT2_IRQHandler ; PIO INT2 +PIN_INT3_IRQHandler ; PIO INT3 +UTICK_IRQHandler ; UTICK timer +MRT_IRQHandler ; Multi-Rate Timer +CT32B0_IRQHandler ; CT32B0 +CT32B1_IRQHandler ; CT32B1 +CT32B2_IRQHandler ; CT32B2 +CT32B3_IRQHandler ; CT32B3 +CT32B4_IRQHandler ; CT32B4 +UART0_IRQHandler ; UART0 +SCT0_IRQHandler ; Smart Counter Timer +UART1_IRQHandler ; UART1 +UART2_IRQHandler ; UART2 +UART3_IRQHandler ; UART3 +I2C0_IRQHandler ; I2C0 controller +I2C1_IRQHandler ; I2C1 controller +I2C2_IRQHandler ; I2C2 controller +SPI0_IRQHandler ; SPI0 controller +SPI1_IRQHandler ; SPI1 controller +ADC_SEQA_IRQHandler ; ADC0 A sequence (A/D Converter) interrupt +ADC_SEQB_IRQHandler ; ADC0 B sequence (A/D Converter) interrupt +ADC_THCMP_IRQHandler ; ADC THCMP and OVERRUN ORed +RTC_IRQHandler ; RTC Timer +MAILBOX_IRQHandler ; Mailbox +GINT1_IRQHandler ; GPIO Group1 Interrupt +PIN_INT4_IRQHandler ; PIO INT4 +PIN_INT5_IRQHandler ; PIO INT5 +PIN_INT6_IRQHandler ; PIO INT6 +PIN_INT7_IRQHandler ; PIO INT7 +RIT_IRQHandler ; RITimer +Reserved41_IRQHandler ; Reserved +Reserved42_IRQHandler ; Reserved +Reserved43_IRQHandler ; Reserved +Reserved44_IRQHandler ; Reserved +Reserved_IRQHandler ; Reserved + + 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 diff --git a/bsp/lpc5410x/Libraries/Device/startup/mtb.c b/bsp/lpc5410x/Libraries/Device/startup/mtb.c new file mode 100644 index 0000000000000000000000000000000000000000..4a653898226160a317968383663d2fcf10e378bd --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/mtb.c @@ -0,0 +1,86 @@ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2013 Code Red Technologies Ltd. +// +// mtb.c +// +// Optionally defines an array to be used as a buffer for Micro Trace +// Buffer (MTB) instruction trace on Cortex-M0+ parts +// +// Version : 130502 +// +// Software License Agreement +// +// The software is owned by Code Red Technologies and/or its suppliers, and is +// protected under applicable copyright laws. All rights are reserved. Any +// use in violation of the foregoing restrictions may subject the user to criminal +// sanctions under applicable laws, as well as to civil liability for the breach +// of the terms and conditions of this license. +// +// 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. +// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT +// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH +// CODE RED TECHNOLOGIES LTD. +// +//***************************************************************************** + +/******************************************************************* + * Symbols controlling behavior of this code... + * + * __MTB_DISABLE + * If this symbol is defined, then the buffer array for the MTB + * will not be created. + * + * __MTB_BUFFER_SIZE + * Symbol specifying the sizer of the buffer array for the MTB. + * This must be a power of 2 in size, and fit into the available + * RAM. The MTB buffer will also be aligned to its 'size' + * boundary and be placed at the start of a RAM bank (which + * should ensure minimal or zero padding due to alignment). + * + * __MTB_RAM_BANK + * Allows MTB Buffer to be placed into specific RAM bank. When + * this is not defined, the "default" (first if there are + * several) RAM bank is used. + *******************************************************************/ + +// Ignore with none Code Red tools +#if defined (__CODE_RED) + +// Allow MTB to be removed by setting a define (via command line) +#if !defined (__MTB_DISABLE) + + // Allow for MTB buffer size being set by define set via command line + // Otherwise provide small default buffer + #if !defined (__MTB_BUFFER_SIZE) + #define __MTB_BUFFER_SIZE 128 + #endif + + // Check that buffer size requested is >0 bytes in size + #if (__MTB_BUFFER_SIZE > 0) + // Pull in MTB related macros + #include + + // Check if MYTB buffer is to be placed in specific RAM bank + #if defined(__MTB_RAM_BANK) + // Place MTB buffer into explicit bank of RAM + __CR_MTB_BUFFER_EXT(__MTB_BUFFER_SIZE,__MTB_RAM_BANK); + #else + // Place MTB buffer into 'default' bank of RAM + __CR_MTB_BUFFER(__MTB_BUFFER_SIZE); + + #endif // defined(__MTB_RAM_BANK) + + #endif // (__MTB_BUFFER_SIZE > 0) + +#endif // !defined (__MTB_DISABLE) + +#endif // defined (__CODE_RED) + diff --git a/bsp/lpc5410x/Libraries/Device/startup/sysinit.c b/bsp/lpc5410x/Libraries/Device/startup/sysinit.c new file mode 100644 index 0000000000000000000000000000000000000000..5a101cb5f8ec5115cd6b1a90efc39633c4950ce8 --- /dev/null +++ b/bsp/lpc5410x/Libraries/Device/startup/sysinit.c @@ -0,0 +1,78 @@ +/* + * @brief Common SystemInit function for LPC54xxx chips + * + * @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 + ****************************************************************************/ +/* Clock rate on the CLKIN pin */ +const uint32_t ExtClockIn = 0; + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + + +/* Set up and initialize hardware prior to call to main */ +void SystemInit(void) +{ +#if defined(__CODE_RED) + extern void(*const g_pfnVectors[]) (void); + SCB->VTOR = (uint32_t) &g_pfnVectors; +#else + //extern void *__Vectors; + //SCB->VTOR = (uint32_t) &isr_vector; + SCB->VTOR = 0x00000000 & 0x3FFFFF80; +#endif + +#if defined(CORE_M4) +#if defined(__FPU_PRESENT) && __FPU_PRESENT == 1 + fpuInit(); +#endif +#endif + +#if !defined(__MULTICORE_M0SLAVE) && !defined(__MULTICORE_M4SLAVE) + /* Chip specific SystemInit */ + Chip_SystemInit(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/SConscript b/bsp/lpc5410x/Libraries/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..4c815c49b835a3a5ea61f337dc17154dd316d7d1 --- /dev/null +++ b/bsp/lpc5410x/Libraries/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +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') diff --git a/bsp/lpc5410x/Libraries/lpc_chip/SConscript b/bsp/lpc5410x/Libraries/lpc_chip/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..5244ddab27d9adfcc2a6f88de044df088438d22b --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/SConscript @@ -0,0 +1,75 @@ +# RT-Thread building script for component + +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() + + + +src = Split(''' +chip_common/fpu_init.c +chip_common/iap.c +chip_common/ring_buffer.c +chip_common/rtc_ut.c + +chip_5410x/chip_5410x.c +chip_5410x/clock_5410x.c +chip_5410x/crc_5410x.c +chip_5410x/fifo_5410x.c +chip_5410x/gpiogroup_5410x.c +chip_5410x/gpio_5410x.c +chip_5410x/hw_adc.c +chip_5410x/hw_dmaaltd.c +chip_5410x/hw_dmaaltd_rom_api.c +chip_5410x/hw_i2cmd.c +chip_5410x/hw_i2cmd_rom_api.c +chip_5410x/hw_i2cmond.c +chip_5410x/hw_i2cmond_rom_api.c +chip_5410x/hw_i2csd.c +chip_5410x/hw_i2csd_rom_api.c +chip_5410x/hw_spimd.c +chip_5410x/hw_spimd_rom_api.c +chip_5410x/hw_spisd.c +chip_5410x/hw_spisd_rom_api.c +chip_5410x/hw_uart.c +chip_5410x/iocon_5410x.c +chip_5410x/pinint_5410x.c +chip_5410x/pll_5410x.c +chip_5410x/ritimer_5410x.c +chip_5410x/romapi_adc.c +chip_5410x/romapi_dma.c +chip_5410x/romapi_i2cm.c +chip_5410x/romapi_i2cmon.c +chip_5410x/romapi_i2cs.c +chip_5410x/romapi_spim.c +chip_5410x/romapi_spis.c +chip_5410x/romapi_uart.c +chip_5410x/rtc_5410x.c +chip_5410x/sct_5410x.c +chip_5410x/sct_pwm_5410x.c +chip_5410x/stopwatch_5410x.c +chip_5410x/syscon_5410x.c +chip_5410x/sysinit_5410x.c +chip_5410x/timer_5410x.c +chip_5410x/utick_5410x.c +chip_5410x/wwdt_5410x.c +''') + + +#LIBS = [cwd + '/chip_5410x/power_lib/keil/lib_power'] + +#lpc_chip\chip_5410x\power_lib\lpcxpresso +# add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + LIBPATH = [cwd + '/chip_5410x/power_lib/lpcxpresso'] + LIBS = ['libpower'] +elif rtconfig.CROSS_TOOL == 'keil': + LIBPATH = [cwd + '/chip_5410x/power_lib/keil'] + LIBS = ['lib_power'] + +CPPPATH = [cwd + '/chip_common',cwd + '/chip_5410x',cwd + '/chip_5410x/config'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH,LIBS = LIBS,LIBPATH=LIBPATH) + +Return('group') diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..5be7e8618fceb0b71b79b0198a658ecab95a85b4 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip.h @@ -0,0 +1,240 @@ +/* + * @brief LPC5410x basic chip inclusion file + * + * @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 __CHIP_H_ +#define __CHIP_H_ + +#include "lpc_types.h" +#include "sys_config.h" +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CORE_M4 +#ifndef CORE_M0PLUS +#error "CORE_M4 or CORE_M0PLUS is not defined for the LPC5410x architecture" +#error "CORE_M4 or CORE_M0PLUS should be defined as part of your compiler define list" +#endif +#endif + +#ifndef CHIP_LPC5410X +#error "The LPC5410X Chip include path is used for this build, but" +#error "CHIP_LPC5410X is not defined!" +#endif + +/** @defgroup PERIPH_5410X_BASE CHIP: LPC5410x Peripheral addresses and register set declarations + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/* Main memory addresses */ +#define LPC_FLASHMEM_BASE 0x00000000UL +#define LPC_SRAM0_BASE 0x02000000UL +#define LPC_SRAM1_BASE 0x02010000UL +#define LPC_ROM_BASE 0x03000000UL +#define LPC_SRAM2_BASE 0x03400000UL +#define LPC_GPIO_PORT_BASE 0x1C000000UL +#define LPC_DMA_BASE 0x1C004000UL +#define LPC_CRC_BASE 0x1C010000UL +#define LPC_SCT_BASE 0x1C018000UL +#define LPC_MBOX_BASE 0x1C02C000UL +#define LPC_ADC_BASE 0x1C034000UL +#define LPC_FIFO_BASE 0x1C038000UL + +/* APB0 peripheral group addresses */ +#define LPC_SYSCON_BASE 0x40000000UL +#define LPC_TIMER2_BASE 0x40004000UL +#define LPC_TIMER3_BASE 0x40008000UL +#define LPC_TIMER4_BASE 0x4000C000UL +#define LPC_GPIO_GROUPINT0_BASE 0x40010000UL +#define LPC_GPIO_GROUPINT1_BASE 0x40014000UL +#define LPC_PIN_INT_BASE 0x40018000UL +#define LPC_IOCON_BASE 0x4001C000UL +#define LPC_UTICK_BASE 0x40020000UL +#define LPC_FMC_BASE 0x40024000UL +#define LPC_PMU_BASE 0x4002C000UL +#define LPC_WWDT_BASE 0x40038000UL +#define LPC_RTC_BASE 0x4003C000UL + +/* APB1 peripheral group addresses */ +#define LPC_ASYNC_SYSCON_BASE 0x40080000UL +#define LPC_USART0_BASE 0x40084000UL +#define LPC_USART1_BASE 0x40088000UL +#define LPC_USART2_BASE 0x4008C000UL +#define LPC_USART3_BASE 0x40090000UL +#define LPC_I2C0_BASE 0x40094000UL +#define LPC_I2C1_BASE 0x40098000UL +#define LPC_I2C2_BASE 0x4009C000UL +#define LPC_SPI0_BASE 0x400A4000UL +#define LPC_SPI1_BASE 0x400A8000UL +#define LPC_TIMER0_BASE 0x400B4000UL +#define LPC_TIMER1_BASE 0x400B8000UL +#define LPC_INMUX_BASE 0x40050000UL +#define LPC_RITIMER_BASE 0x40070000UL +#define LPC_MRT_BASE 0x40074000UL + +/* Main memory register access */ +#define LPC_GPIO ((LPC_GPIO_T *) LPC_GPIO_PORT_BASE) +#define LPC_DMA ((LPC_DMA_T *) LPC_DMA_BASE) +#define LPC_CRC ((LPC_CRC_T *) LPC_CRC_BASE) +#define LPC_SCT ((LPC_SCT_T *) LPC_SCT_BASE) +#define LPC_MBOX ((LPC_MBOX_T *) LPC_MBOX_BASE) +#define LPC_ADC ((LPC_ADC_T *) LPC_ADC_BASE) +#define LPC_FIFO ((LPC_FIFO_T *) LPC_FIFO_BASE) + +/* APB0 peripheral group register access */ +#define LPC_SYSCON ((LPC_SYSCON_T *) LPC_SYSCON_BASE) +#define LPC_TIMER2 ((LPC_TIMER_T *) LPC_TIMER2_BASE) +#define LPC_TIMER3 ((LPC_TIMER_T *) LPC_TIMER3_BASE) +#define LPC_TIMER4 ((LPC_TIMER_T *) LPC_TIMER4_BASE) +#define LPC_GINT ((LPC_GPIOGROUPINT_T *) LPC_GPIO_GROUPINT0_BASE) +#define LPC_PININT ((LPC_PIN_INT_T *) LPC_PIN_INT_BASE) +#define LPC_IOCON ((LPC_IOCON_T *) LPC_IOCON_BASE) +#define LPC_UTICK ((LPC_UTICK_T *) LPC_UTICK_BASE) +#define LPC_WWDT ((LPC_WWDT_T *) LPC_WWDT_BASE) +#define LPC_RTC ((LPC_RTC_T *) LPC_RTC_BASE) + +/* APB1 peripheral group register access */ +#define LPC_ASYNC_SYSCON ((LPC_ASYNC_SYSCON_T *) LPC_ASYNC_SYSCON_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_USART3 ((LPC_USART_T *) LPC_USART3_BASE) +#define LPC_I2C0 ((LPC_I2C_T *) LPC_I2C0_BASE) +#define LPC_I2C1 ((LPC_I2C_T *) LPC_I2C1_BASE) +#define LPC_I2C2 ((LPC_I2C_T *) LPC_I2C2_BASE) +#define LPC_SCT0 LPC_SCT +#define LPC_SPI0 ((LPC_SPI_T *) LPC_SPI0_BASE) +#define LPC_SPI1 ((LPC_SPI_T *) LPC_SPI1_BASE) +#define LPC_TIMER0 ((LPC_TIMER_T *) LPC_TIMER0_BASE) +#define LPC_TIMER1 ((LPC_TIMER_T *) LPC_TIMER1_BASE) +#define LPC_INMUX ((LPC_INMUX_T *) LPC_INMUX_BASE) +#define LPC_RITIMER ((LPC_RITIMER_T *) LPC_RITIMER_BASE) +#define LPC_MRT ((LPC_MRT_T *) LPC_MRT_BASE) +#define LPC_PMU ((LPC_PMU_T *) LPC_PMU_BASE) + +/** + * @} + */ + +/** @ingroup CHIP_5410X_DRIVER_OPTIONS + * @{ + */ + +/** + * @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 ExtClockIn; + +/** + * @} + */ + +/* Èç¹û²»ÓÃĪ¸öÎļþ£¬È¥µôÏàÓ¦µÄÎļþ£¬¿ÉÒÔ */ + +/* Include order is important! */ +#include "romapi_5410x.h" +#include "syscon_5410x.h" +#include "cpuctrl_5410x.h" +#include "clock_5410x.h" +#include "pmu_5410x.h" +#include "iocon_5410x.h" +#include "pinint_5410x.h" +#include "inmux_5410x.h" +#include "crc_5410x.h" +#include "gpio_5410x.h" +#include "fifo_5410x.h" +#include "mrt_5410x.h" +#include "wwdt_5410x.h" +#include "sct_5410x.h" +#include "sct_pwm_5410x.h" +#include "rtc_5410x.h" +#include "timer_5410x.h" +#include "ritimer_5410x.h" +#include "utick_5410x.h" +#include "gpiogroup_5410x.h" +#include "mailbox_5410x.h" +#include "fpu_init.h" +#include "power_lib_5410x.h" + +/** @defgroup SUPPORT_5410X_FUNC CHIP: LPC5410x support functions + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief Current system clock rate, mainly used for peripherals in SYSCON + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Update system core and ASYNC syscon 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 internal oscillator + * @param iFreq : Rate (in Hz) to set the main system clock to + * @return None + */ +void Chip_SetupIrcClocking(uint32_t iFreq); + +/** + * @brief Clock and PLL initialization based on the external clock input + * @param iFreq : Rate (in Hz) to set the main system clock to + * @return None + */ +void Chip_SetupExtInClocking(uint32_t iFreq); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CHIP_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..38d5c63ce81e3afacdf4e559c704e0184e3f760a --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/chip_5410x.c @@ -0,0 +1,59 @@ +/* + * @brief LPC5410X Miscellaneous chip specific functions + * + * @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 + ****************************************************************************/ + +/* System Clock Frequency (Core Clock) */ +uint32_t SystemCoreClock; + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Update system core clock rate, should be called if the system has + a clock rate change */ +void SystemCoreClockUpdate(void) +{ + /* CPU core speed (main clock speed adjusted by system clock divider) */ + SystemCoreClock = Chip_Clock_GetSystemClockRate(); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..2512498fed05f99778ac6bc91abe1553c729522b --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.c @@ -0,0 +1,393 @@ +/* + * @brief LPC5410X clock 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 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 + ****************************************************************************/ + +/* Return asynchronous APB clock rate (no regard for divider) */ +static uint32_t Chip_Clock_GetAsyncSyscon_ClockRate_NoDiv(void) +{ + CHIP_ASYNC_SYSCON_SRC_T src; + uint32_t clkRate; + + src = Chip_Clock_GetAsyncSysconClockSource(); + switch (src) { + case SYSCON_ASYNC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCON_ASYNC_WDTOSC: + clkRate = Chip_Clock_GetWDTOSCRate(); + break; + + case SYSCON_ASYNC_MAINCLK: + clkRate = Chip_Clock_GetMainClockRate(); + break; + + case SYSCON_ASYNC_CLKIN: + clkRate = Chip_Clock_GetSystemPLLInClockRate(); + break; + + case SYSCON_ASYNC_SYSPLLOUT: + clkRate = Chip_Clock_GetSystemPLLOutClockRate(false); + break; + + default: + clkRate = 0; + break; + } + + return clkRate; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Return main A clock rate */ +uint32_t Chip_Clock_GetMain_A_ClockRate(void) +{ + uint32_t clkRate = 0; + + switch (Chip_Clock_GetMain_A_ClockSource()) { + case SYSCON_MAIN_A_CLKSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCON_MAIN_A_CLKSRCA_CLKIN: + clkRate = Chip_Clock_GetExtClockInRate(); + break; + + case SYSCON_MAIN_A_CLKSRCA_WDTOSC: + clkRate = Chip_Clock_GetWDTOSCRate(); + break; + + default: + clkRate = 0; + break; + } + + return clkRate; +} + +/* Return main B clock rate */ +uint32_t Chip_Clock_GetMain_B_ClockRate(void) +{ + uint32_t clkRate = 0; + + switch (Chip_Clock_GetMain_B_ClockSource()) { + case SYSCON_MAIN_B_CLKSRC_MAINCLKSELA: + clkRate = Chip_Clock_GetMain_A_ClockRate(); + break; + + case SYSCON_MAIN_B_CLKSRC_SYSPLLIN: + clkRate = Chip_Clock_GetSystemPLLInClockRate(); + break; + + case SYSCON_MAIN_B_CLKSRC_SYSPLLOUT: + clkRate = Chip_Clock_GetSystemPLLOutClockRate(false); + break; + + case SYSCON_MAIN_B_CLKSRC_RTC: + clkRate = Chip_Clock_GetRTCOscRate(); + break; + } + + return clkRate; +} + +/* Set CLKOUT clock source and divider */ +void Chip_Clock_SetCLKOUTSource(CHIP_SYSCON_CLKOUTSRC_T src, uint32_t div) +{ + uint32_t srcClk = (uint32_t) src; + + /* Use a clock A source? */ + if (src >= SYSCON_CLKOUTSRCA_OUTPUT) { + /* Not using a CLKOUT A source */ + LPC_SYSCON->CLKOUTSELB = srcClk - SYSCON_CLKOUTSRCA_OUTPUT; + } + else { + /* Using a clock A source, select A and then switch B to A */ + LPC_SYSCON->CLKOUTSELA = srcClk; + LPC_SYSCON->CLKOUTSELB = 0; + } + + LPC_SYSCON->CLKOUTDIV = div; +} + +/* Enable a system or peripheral clock */ +void Chip_Clock_EnablePeriphClock(CHIP_SYSCON_CLOCK_T clk) +{ + uint32_t clkEnab = (uint32_t) clk; + + if (clkEnab >= 128) { + clkEnab = clkEnab - 128; + + LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1 << clkEnab); + } + else if (clkEnab >= 32) { + LPC_SYSCON->AHBCLKCTRLSET[1] = (1 << (clkEnab - 32)); + } + else { + LPC_SYSCON->AHBCLKCTRLSET[0] = (1 << clkEnab); + } +} + +/* Disable a system or peripheral clock */ +void Chip_Clock_DisablePeriphClock(CHIP_SYSCON_CLOCK_T clk) +{ + uint32_t clkEnab = (uint32_t) clk; + + if (clkEnab >= 128) { + clkEnab = clkEnab - 128; + + LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1 << clkEnab); + } + else if (clkEnab >= 32) { + LPC_SYSCON->AHBCLKCTRLCLR[1] = (1 << (clkEnab - 32)); + } + else { + LPC_SYSCON->AHBCLKCTRLCLR[0] = (1 << clkEnab); + } +} + +/* Returns the system tick rate as used with the system tick divider */ +uint32_t Chip_Clock_GetSysTickClockRate(void) +{ + uint32_t sysRate, div; + + div = LPC_SYSCON->SYSTICKCLKDIV; + + /* If divider is 0, the system tick clock is disabled */ + if (div == 0) { + sysRate = 0; + } + else { + sysRate = Chip_Clock_GetSystemClockRate() / LPC_SYSCON->SYSTICKCLKDIV; + } + + return sysRate; +} + +/* Return ADC clock rate */ +uint32_t Chip_Clock_GetADCClockRate(void) +{ + uint32_t div, clkRate = 0; + + div = Chip_Clock_GetADCClockDiv(); + + /* ADC clock only enabled if div>0 */ + if (div > 0) { + switch (Chip_Clock_GetADCClockSource()) { + case SYSCON_ADCCLKSELSRC_MAINCLK: + clkRate = Chip_Clock_GetMainClockRate(); + break; + + case SYSCON_ADCCLKSELSRC_SYSPLLOUT: + clkRate = Chip_Clock_GetSystemPLLOutClockRate(false); + break; + + case SYSCON_ADCCLKSELSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + } + + clkRate = clkRate / div; + } + + return clkRate; +} + +/* Set asynchronous APB clock source */ +void Chip_Clock_SetAsyncSysconClockSource(CHIP_ASYNC_SYSCON_SRC_T src) +{ + uint32_t clkSrc = (uint32_t) src; + + if (src >= SYSCON_ASYNC_MAINCLK) { + LPC_ASYNC_SYSCON->ASYNCAPBCLKSELB = (clkSrc - 4); + } + else { + LPC_ASYNC_SYSCON->ASYNCAPBCLKSELA = clkSrc; + LPC_ASYNC_SYSCON->ASYNCAPBCLKSELB = 3; + } +} + +/* Get asynchronous APB clock source */ +CHIP_ASYNC_SYSCON_SRC_T Chip_Clock_GetAsyncSysconClockSource(void) +{ + uint32_t clkSrc; + + if (LPC_ASYNC_SYSCON->ASYNCAPBCLKSELB == 3) { + clkSrc = LPC_ASYNC_SYSCON->ASYNCAPBCLKSELA; + } + else { + clkSrc = 4 + LPC_ASYNC_SYSCON->ASYNCAPBCLKSELB; + } + + return (CHIP_ASYNC_SYSCON_SRC_T) clkSrc; +} + +/* Return asynchronous APB clock rate */ +uint32_t Chip_Clock_GetAsyncSyscon_ClockRate(void) +{ + uint32_t clkRate, div; + + clkRate = Chip_Clock_GetAsyncSyscon_ClockRate_NoDiv(); + div = LPC_ASYNC_SYSCON->ASYNCCLKDIV; + if (div == 0) { + /* Clock is disabled */ + return 0; + } + + return clkRate / div; +} + +/* Set main system clock source */ +void Chip_Clock_SetMainClockSource(CHIP_SYSCON_MAINCLKSRC_T src) +{ + uint32_t clkSrc = (uint32_t) src; + + if (clkSrc >= 4) { + /* Main B source only, not using main A */ + Chip_Clock_SetMain_B_ClockSource((CHIP_SYSCON_MAIN_B_CLKSRC_T) (clkSrc - 4)); + } + else { + /* Select main A clock source and set main B source to use main A */ + Chip_Clock_SetMain_A_ClockSource((CHIP_SYSCON_MAIN_A_CLKSRC_T) clkSrc); + Chip_Clock_SetMain_B_ClockSource(SYSCON_MAIN_B_CLKSRC_MAINCLKSELA); + } +} + +/* Returns the main clock source */ +CHIP_SYSCON_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void) +{ + CHIP_SYSCON_MAIN_B_CLKSRC_T srcB; + uint32_t clkSrc; + + /* Get main B clock source */ + srcB = Chip_Clock_GetMain_B_ClockSource(); + if (srcB == SYSCON_MAIN_B_CLKSRC_MAINCLKSELA) { + /* Using source A, so return source A */ + clkSrc = (uint32_t) Chip_Clock_GetMain_A_ClockSource(); + } + else { + /* Using source B */ + clkSrc = 4 + (uint32_t) srcB; + } + + return (CHIP_SYSCON_MAINCLKSRC_T) clkSrc; +} + +/* Return main clock rate */ +uint32_t Chip_Clock_GetMainClockRate(void) +{ + uint32_t clkRate; + + if (Chip_Clock_GetMain_B_ClockSource() == SYSCON_MAIN_B_CLKSRC_MAINCLKSELA) { + /* Return main A clock rate */ + clkRate = Chip_Clock_GetMain_A_ClockRate(); + } + else { + /* Return main B clock rate */ + clkRate = Chip_Clock_GetMain_B_ClockRate(); + } + + 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_SYSCON->AHBCLKDIV; +} + +/* Get UART base rate */ +uint32_t Chip_Clock_GetUARTBaseClockRate(void) +{ + uint64_t inclk; + + /* Get clock rate into FRG */ + inclk = (uint64_t) Chip_Clock_GetAsyncSyscon_ClockRate(); + + if (inclk != 0) { + uint32_t mult, divmult; + + divmult = LPC_ASYNC_SYSCON->FRGCTRL & 0xFF; + if ((divmult & 0xFF) == 0xFF) { + /* Fractional part is enabled, get multiplier */ + mult = (divmult >> 8) & 0xFF; + + /* Get fractional error */ + inclk = (inclk * 256) / (uint64_t) (256 + mult); + } + } + + return (uint32_t) inclk; +} + +/* Set UART base rate */ +uint32_t Chip_Clock_SetUARTBaseClockRate(uint32_t rate) +{ + uint32_t div, inclk, err; + uint64_t uart_fra_multiplier; + + /* Input clock into FRG block is the main system cloock */ + inclk = Chip_Clock_GetAsyncSyscon_ClockRate(); + + /* Get integer divider for coarse rate */ + div = inclk / rate; + if (div == 0) { + div = 1; + } + + /* Enable FRG clock */ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_FRG); + + err = inclk - (rate * div); + uart_fra_multiplier = (((uint64_t) err + (uint64_t) rate) * 256) / (uint64_t) (rate * div); + + /* Enable fractional divider and set multiplier */ + LPC_ASYNC_SYSCON->FRGCTRL = 0xFF | (uart_fra_multiplier << 8); + + return Chip_Clock_GetUARTBaseClockRate(); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..31b47539e91b19c537bc925ac45df61678d01fc3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.h @@ -0,0 +1,473 @@ +/* + * @brief LPC5410X clock 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 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_5410X_H_ +#define __CLOCK_5410X_H_ + +#include "pll_5410x.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CLOCK_5410X CHIP: LPC5410X Clock Driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/* Internal oscillator frequency */ +#define SYSCON_IRC_FREQ (12000000) +#define SYSCON_WDTOSC_FREQ (500000) +#define SYSCON_RTC_FREQ (32768) + +/** + * @brief Returns the internal oscillator (IRC) clock rate + * @return internal oscillator (IRC) clock rate + */ +STATIC INLINE uint32_t Chip_Clock_GetIntOscRate(void) +{ + return SYSCON_IRC_FREQ; +} + +/** + * @brief Returns the external clock input rate + * @return External clock input rate + */ +STATIC INLINE uint32_t Chip_Clock_GetExtClockInRate(void) +{ + return ExtClockIn; +} + +/** + * @brief Returns the RTC clock rate + * @return RTC oscillator clock rate in Hz + */ +STATIC INLINE uint32_t Chip_Clock_GetRTCOscRate(void) +{ + return SYSCON_RTC_FREQ; +} + +/** + * @brief Return estimated watchdog oscillator rate + * @return Estimated watchdog oscillator rate + * @note This rate is accurate to plus or minus 40%. + */ +STATIC INLINE uint32_t Chip_Clock_GetWDTOSCRate(void) +{ + return SYSCON_WDTOSC_FREQ; +} + +/** + * Clock source selections for only the main A system clock. The main A system + * clock is used as an input into the main B system clock selector. Main clock A + * only needs to be setup if the main clock A input is used in the main clock + * system selector. + */ +typedef enum { + SYSCON_MAIN_A_CLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCON_MAIN_A_CLKSRCA_CLKIN, /*!< Crystal (main) oscillator in */ + SYSCON_MAIN_A_CLKSRCA_WDTOSC, /*!< Watchdog oscillator rate */ +} CHIP_SYSCON_MAIN_A_CLKSRC_T; + +/** + * @brief Set main A system clock source + * @param src : Clock source for main A + * @return Nothing + * @note This function only needs to be setup if main clock A will be + * selected in the Chip_Clock_GetMain_B_ClockRate() function. + */ +STATIC INLINE void Chip_Clock_SetMain_A_ClockSource(CHIP_SYSCON_MAIN_A_CLKSRC_T src) +{ + LPC_SYSCON->MAINCLKSELA = (uint32_t) src; +} + +/** + * @brief Returns the main A clock source + * @return Returns which clock is used for the main A + */ +STATIC INLINE CHIP_SYSCON_MAIN_A_CLKSRC_T Chip_Clock_GetMain_A_ClockSource(void) +{ + return (CHIP_SYSCON_MAIN_A_CLKSRC_T) (LPC_SYSCON->MAINCLKSELA); +} + +/** + * @brief Return main A clock rate + * @return main A clock rate in Hz + */ +uint32_t Chip_Clock_GetMain_A_ClockRate(void); + +/** + * Clock sources for only main B system clock + */ +typedef enum { + SYSCON_MAIN_B_CLKSRC_MAINCLKSELA = 0, /*!< main clock A */ + SYSCON_MAIN_B_CLKSRC_SYSPLLIN, /*!< System PLL input */ + SYSCON_MAIN_B_CLKSRC_SYSPLLOUT, /*!< System PLL output */ + SYSCON_MAIN_B_CLKSRC_RTC, /*!< RTC oscillator 32KHz output */ +} CHIP_SYSCON_MAIN_B_CLKSRC_T; + +/** + * @brief Set main B system clock source + * @param src : Clock source for main B + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetMain_B_ClockSource(CHIP_SYSCON_MAIN_B_CLKSRC_T src) +{ + LPC_SYSCON->MAINCLKSELB = (uint32_t) src; +} + +/** + * @brief Returns the main B clock source + * @return Returns which clock is used for the main B + */ +STATIC INLINE CHIP_SYSCON_MAIN_B_CLKSRC_T Chip_Clock_GetMain_B_ClockSource(void) +{ + return (CHIP_SYSCON_MAIN_B_CLKSRC_T) (LPC_SYSCON->MAINCLKSELB); +} + +/** + * @brief Return main B clock rate + * @return main B clock rate + */ +uint32_t Chip_Clock_GetMain_B_ClockRate(void); + +/** + * Clock sources for CLKOUT + */ +typedef enum { + SYSCON_CLKOUTSRC_MAINCLK = 0, /*!< Main system clock for CLKOUT */ + SYSCON_CLKOUTSRC_CLKIN, /*!< CLKIN for CLKOUT */ + SYSCON_CLKOUTSRC_WDTOSC, /*!< Watchdog oscillator for CLKOUT */ + SYSCON_CLKOUTSRC_IRC, /*!< Internal oscillator for CLKOUT */ + SYSCON_CLKOUTSRCA_OUTPUT, /*!< clkoutA output route to input of clkoutB */ + SYSCON_CLKOUTSRC_RTC = 7 /*!< RTC oscillator 32KHz for CLKOUT */ +} CHIP_SYSCON_CLKOUTSRC_T; + +/** + * @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_SYSCON_CLKOUTSRC_T src, uint32_t div); + +/** + * System and peripheral clocks enum + */ +typedef enum CHIP_SYSCON_CLOCK { + /* Peripheral clock enables for SYSAHBCLKCTRL0 */ + SYSCON_CLOCK_ROM = 1, /*!< ROM clock */ + SYSCON_CLOCK_SRAM1 = 3, /*!< SRAM1 clock */ + SYSCON_CLOCK_SRAM2, /*!< SRAM2 clock */ + SYSCON_CLOCK_FLASH = 7, /*!< FLASH controller clock */ + SYSCON_CLOCK_FMC, /*!< FMC clock */ + SYSCON_CLOCK_INPUTMUX = 11, /*!< Input mux clock */ + SYSCON_CLOCK_IOCON = 13, /*!< IOCON clock */ + SYSCON_CLOCK_GPIO0, /*!< GPIO0 clock */ + SYSCON_CLOCK_GPIO1, /*!< GPIO1 clock */ + SYSCON_CLOCK_PINT = 18, /*!< PININT clock */ + SYSCON_CLOCK_GINT, /*!< grouped pin interrupt block clock */ + SYSCON_CLOCK_DMA, /*!< DMA clock */ + SYSCON_CLOCK_CRC, /*!< CRC clock */ + SYSCON_CLOCK_WWDT, /*!< WDT clock */ + SYSCON_CLOCK_RTC, /*!< RTC clock */ + SYSCON_CLOCK_MAILBOX = 26, /*!< Mailbox clock */ + SYSCON_CLOCK_ADC0, /*!< ADC0 clock */ + + /* Peripheral clock enables for SYSAHBCLKCTRL1 */ + SYSCON_CLOCK_MRT = 32, /*!< multi-rate timer clock */ + SYSCON_CLOCK_RIT, /*!< Repetitive interval timer clock */ + SYSCON_CLOCK_SCT0, /*!< SCT0 clock */ + SYSCON_CLOCK_FIFO = 32 + 9, /*!< System FIFO clock */ + SYSCON_CLOCK_UTICK, /*!< UTICK clock */ + SYSCON_CLOCK_TIMER2 = 32 + 22, /*!< TIMER2 clock */ + SYSCON_CLOCK_TIMER3 = 32 + 26, /*!< TIMER3 clock */ + SYSCON_CLOCK_TIMER4, /*!< TIMER4 clock */ + + /* Peripheral clock enables for ASYNCAPBCLKCTRLCLR */ + SYSCON_CLOCK_USART0 = 128 + 1, /*!< USART0 clock */ + SYSCON_CLOCK_USART1, /*!< USART1 clock */ + SYSCON_CLOCK_USART2, /*!< USART2 clock */ + SYSCON_CLOCK_USART3, /*!< USART3 clock */ + SYSCON_CLOCK_I2C0, /*!< I2C0 clock */ + SYSCON_CLOCK_I2C1, /*!< I2C1 clock */ + SYSCON_CLOCK_I2C2, /*!< I2C2 clock */ + SYSCON_CLOCK_SPI0 = 128 + 9, /*!< SPI0 clock */ + SYSCON_CLOCK_SPI1, /*!< SPI1 clock */ + SYSCON_CLOCK_TIMER0 = 128 + 13, /*!< TIMER0 clock */ + SYSCON_CLOCK_TIMER1, /*!< TIMER1 clock */ + SYSCON_CLOCK_FRG /*!< FRG clock */ +} CHIP_SYSCON_CLOCK_T; + +/** + * @brief Enable a system or peripheral clock + * @param clk : Clock to enable + * @return Nothing + */ +void Chip_Clock_EnablePeriphClock(CHIP_SYSCON_CLOCK_T clk); + +/** + * @brief Disable a system or peripheral clock + * @param clk : Clock to disable + * @return Nothing + */ +void Chip_Clock_DisablePeriphClock(CHIP_SYSCON_CLOCK_T clk); + +/** + * @brief Set system tick clock divider (external CLKIN as SYSTICK reference only) + * @param div : divider for system clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The system tick + * rate is the external CLKIN rate divided by this value. The extern CLKIN pin + * signal, divided by the SYSTICKCLKDIV divider, is selected by clearing + * CLKSOURCE bit 2 in the System Tick CSR register. The core clock must be at least + * 2.5 times faster than the reference system tick clock otherwise the count + * values are unpredictable. + */ +STATIC INLINE void Chip_Clock_SetSysTickClockDiv(uint32_t div) +{ + LPC_SYSCON->SYSTICKCLKDIV = div; +} + +/** + * @brief Returns system tick clock divider + * @return system tick clock divider + */ +STATIC INLINE uint32_t Chip_Clock_GetSysTickClockDiv(void) +{ + return LPC_SYSCON->SYSTICKCLKDIV; +} + +/** + * @brief Returns the system tick rate as used with the system tick divider + * @return the system tick rate + */ +uint32_t Chip_Clock_GetSysTickClockRate(void); + +/** + * @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_SYSCON->AHBCLKDIV = div; +} + +/** + * @brief Set system tick 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 tick + * rate is the main system clock divided by this value. Use caution when using + * the CMSIS SysTick_Config() functions as they typically use SystemCoreClock + * for setup. + */ +STATIC INLINE void Chip_Clock_SetADCClockDiv(uint32_t div) +{ + LPC_SYSCON->ADCCLKDIV = div; +} + +/** + * @brief Returns ADC clock divider + * @return ADC clock divider, 0 = disabled + */ +STATIC INLINE uint32_t Chip_Clock_GetADCClockDiv(void) +{ + return LPC_SYSCON->ADCCLKDIV; +} + +/** + * Clock sources for ADC clock source select + */ +typedef enum { + SYSCON_ADCCLKSELSRC_MAINCLK = 0, /*!< Main clock */ + SYSCON_ADCCLKSELSRC_SYSPLLOUT, /*!< PLL output */ + SYSCON_ADCCLKSELSRC_IRC /*!< Internal oscillator */ +} CHIP_SYSCON_ADCCLKSELSRC_T; + +/** + * @brief Set the ADC clock source + * @param src : ADC clock source + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetADCClockSource(CHIP_SYSCON_ADCCLKSELSRC_T src) +{ + LPC_SYSCON->ADCCLKSEL = (uint32_t) src; +} + +/** + * @brief Returns the ADC clock source + * @return Returns which clock is used for the ADC clock source + */ +STATIC INLINE CHIP_SYSCON_ADCCLKSELSRC_T Chip_Clock_GetADCClockSource(void) +{ + return (CHIP_SYSCON_ADCCLKSELSRC_T) (LPC_SYSCON->ADCCLKSEL); +} + +/** + * @brief Return ADC clock rate + * @return ADC clock rate + */ +uint32_t Chip_Clock_GetADCClockRate(void); + +/** + * @brief Enable the RTC 32KHz output + * @return Nothing + * @note This clock can be used for the main clock directly, but + * do not use this clock with the system PLL. + */ +STATIC INLINE void Chip_Clock_EnableRTCOsc(void) +{ + LPC_SYSCON->RTCOSCCTRL = 1; +} + +/** + * @brief Disable the RTC 32KHz output + * @return Nothing + */ +STATIC INLINE void Chip_Clock_DisableRTCOsc(void) +{ + LPC_SYSCON->RTCOSCCTRL = 0; +} + +/** + * Clock source selections for the asynchronous APB clock + */ +typedef enum { + SYSCON_ASYNC_IRC = 0, /*!< IRC input */ + SYSCON_ASYNC_WDTOSC, /*!< Watchdog oscillator */ + SYSCON_ASYNC_MAINCLK = 4, /*!< Main clock */ + SYSCON_ASYNC_CLKIN, /*!< external CLK input */ + SYSCON_ASYNC_SYSPLLOUT /*!< System PLL output */ +} CHIP_ASYNC_SYSCON_SRC_T; + +/** + * @brief Set asynchronous APB clock source + * @param src : Clock source for asynchronous APB clock + * @return Nothing + */ +void Chip_Clock_SetAsyncSysconClockSource(CHIP_ASYNC_SYSCON_SRC_T src); + +/** + * @brief Get asynchronous APB clock source + * @return Clock source for asynchronous APB clock + */ +CHIP_ASYNC_SYSCON_SRC_T Chip_Clock_GetAsyncSysconClockSource(void); + +/** + * @brief Return asynchronous APB clock rate + * @return Asynchronous APB clock rate + * @note Includes adjustments by Async clock divider (ASYNCCLKDIV). + */ +uint32_t Chip_Clock_GetAsyncSyscon_ClockRate(void); + +/** + * @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_SetAsyncSysconClockDiv(uint32_t div) +{ + LPC_ASYNC_SYSCON->ASYNCCLKDIV = div; +} + +/** + * Clock sources for main system clock. This is a mix of both main clock A + * and B selections. + */ +typedef enum { + SYSCON_MAINCLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCON_MAINCLKSRC_CLKIN, /*!< Crystal (main) oscillator in */ + SYSCON_MAINCLKSRC_WDTOSC, /*!< Watchdog oscillator rate */ + SYSCON_MAINCLKSRC_PLLIN = 5, /*!< System PLL input */ + SYSCON_MAINCLKSRC_PLLOUT, /*!< System PLL output */ + SYSCON_MAINCLKSRC_RTC /*!< RTC oscillator 32KHz output */ +} CHIP_SYSCON_MAINCLKSRC_T; + +/** + * @brief Set main system clock source + * @param src : Clock source for main system + * @return Nothing + */ +void Chip_Clock_SetMainClockSource(CHIP_SYSCON_MAINCLKSRC_T src); + +/** + * @brief Get main system clock source + * @return Clock source for main system + * @note + */ +CHIP_SYSCON_MAINCLKSRC_T Chip_Clock_GetMainClockSource(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 + * @note This is the main clock rate divided by AHBCLKDIV. + */ +uint32_t Chip_Clock_GetSystemClockRate(void); + +/** + * @brief Get UART base clock rate + * @return UART base clock rate + */ +uint32_t Chip_Clock_GetUARTBaseClockRate(void); + +/** + * @brief Get UART base clock rate using FRG + * @return Actual UART base clock rate + * @note It's recommended to set a base rate at least 16x the + * expected maximum UART transfer bit rate. + */ +uint32_t Chip_Clock_SetUARTBaseClockRate(uint32_t rate); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CLOCK_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmd.bat b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmd.bat new file mode 100644 index 0000000000000000000000000000000000000000..602c0a702465b7aa02a1adb4af9237defc5fcde2 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmd.bat @@ -0,0 +1 @@ +dir *.c >C:\Users\Administrator\Desktop\c.txt \ No newline at end of file diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmsis.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmsis.h new file mode 100644 index 0000000000000000000000000000000000000000..bd1047d3adb4f0beb413cb264216bcc1d6ad2135 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cmsis.h @@ -0,0 +1,56 @@ +/* + * @brief LPC5410x selective CMSIS inclusion file + * + * Copyright(C) NXP Semiconductors, 2014 + * 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. + */ + +#ifndef __CMSIS_H_ +#define __CMSIS_H_ + +#include "lpc_types.h" +#include "sys_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Select correct CMSIS include file based on CORE_* definition */ +#if defined(CORE_M4) +#include "cmsis_5410x.h" +typedef LPC5410X_IRQn_Type IRQn_Type; +#include "core_cm4.h" /*!< Cortex-M4 processor and core peripherals */ +#elif defined(CORE_M0PLUS) +#include "cmsis_5410x_m0.h" +typedef LPC5410X_M0_IRQn_Type IRQn_Type; +#include "core_cm0plus.h" /*!< Cortex-M0 Plus processor and core peripherals */ +#else +#error "No CORE_* definition is defined" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config.xml b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config.xml new file mode 100644 index 0000000000000000000000000000000000000000..7e3976331d7cb0bae532e7cdee79ebbcd02e6e8c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..a32c7c516574c1956195fb380de6ec2b01cc849b --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x.h @@ -0,0 +1,172 @@ +/* + * @brief Basic CMSIS include file for LPC5410x M4 core + * + * @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 __CMSIS_5410X_H_ +#define __CMSIS_5410X_H_ + +#include "lpc_types.h" +#include "sys_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CMSIS_5410X_M4 CHIP: LPC5410X M4 core CMSIS include file + * @ingroup CHIP_5410X_CMSIS_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 + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +#if !defined(CORE_M4) +#error "CORE_M4 is not defined" +#endif + +/** @defgroup CMSIS_5410X_M4_IRQ CHIP_5410X: LPC5410X M4 core peripheral interrupt numbers + * @{ + */ + +typedef enum { + /****** Cortex-M4 Processor Exceptions Numbers ***************************************************/ + Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management, MPU mismatch, including Access Violation and No Match */ + BusFault_IRQn = -11, /*!< 5 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */ + PendSV_IRQn = -2, /*!< 14 Pendable request for system service */ + SysTick_IRQn = -1, /*!< 15 System Tick Timer */ + + /****** LPC5410X Specific Interrupt Numbers ********************************************************/ + WDT_IRQn = 0, /*!< WWDT */ + BOD_IRQn = 1, /*!< BOD */ + Reserved2_IRQn = 2, /*!< Reserved Interrupt */ + DMA_IRQn = 3, /*!< DMA */ + GINT0_IRQn = 4, /*!< GINT0 */ + PIN_INT0_IRQn = 5, /*!< PININT0 */ + PIN_INT1_IRQn = 6, /*!< PININT1 */ + PIN_INT2_IRQn = 7, /*!< PININT2 */ + PIN_INT3_IRQn = 8, /*!< PININT3 */ + UTICK_IRQn = 9, /*!< Micro-tick Timer interrupt */ + MRT_IRQn = 10, /*!< Multi-rate timer interrupt */ + CT32B0_IRQn = 11, /*!< CTMR0 */ + CT32B1_IRQn = 12, /*!< CTMR1 */ + CT32B2_IRQn = 13, /*!< CTMR2 */ + CT32B3_IRQn = 14, /*!< CTMR3 */ + CT32B4_IRQn = 15, /*!< CTMR4 */ + SCT0_IRQn = 16, /*!< SCT */ + UART0_IRQn = 17, /*!< UART0 */ + UART1_IRQn = 18, /*!< UART1 */ + UART2_IRQn = 19, /*!< UART2 */ + UART3_IRQn = 20, /*!< UART3 */ + I2C0_IRQn = 21, /*!< I2C0 */ + I2C1_IRQn = 22, /*!< I2C1 */ + I2C2_IRQn = 23, /*!< I2C2 */ + SPI0_IRQn = 24, /*!< SPI0 */ + SPI1_IRQn = 25, /*!< SPI1 */ + ADC_SEQA_IRQn = 26, /*!< ADC0 sequence A completion */ + ADC_SEQB_IRQn = 27, /*!< ADC0 sequence B completion */ + ADC_THCMP_IRQn = 28, /*!< ADC0 threshold compare and error */ + RTC_IRQn = 29, /*!< RTC alarm and wake-up interrupts */ + Reserved30_IRQn = 30, /*!< Reserved Interrupt */ + MAILBOX_IRQn = 31, /*!< Mailbox */ + GINT1_IRQn = 32, /*!< GINT1 */ + PIN_INT4_IRQn = 33, /*!< External Interrupt 4 */ + PIN_INT5_IRQn = 34, /*!< External Interrupt 5 */ + PIN_INT6_IRQn = 35, /*!< External Interrupt 6 */ + PIN_INT7_IRQn = 36, /*!< External Interrupt 7 */ + Reserved37_IRQn = 37, /*!< Reserved Interrupt */ + Reserved38_IRQn = 38, /*!< Reserved Interrupt */ + Reserved39_IRQn = 39, /*!< Reserved Interrupt */ + RIT_IRQn = 40, /*!< Repetitive Interrupt Timer */ + Reserved41_IRQn = 41, /*!< Reserved Interrupt */ + Reserved42_IRQn = 42, /*!< Reserved Interrupt */ + Reserved43_IRQn = 43, /*!< Reserved Interrupt */ + Reserved44_IRQn = 44, /*!< Reserved Interrupt */ +} LPC5410X_IRQn_Type; + +/** + * @} + */ + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/** @defgroup CMSIS_5410X_M4_COMMON CHIP: LPC5410X M4 core Cortex CMSIS definitions + * @{ + */ + +/* Configuration of the Cortex-M4 Processor and Core Peripherals */ +#define __CM4_REV 0x0001 /*!< Cortex-M4 Core Revision */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x_m0.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x_m0.h new file mode 100644 index 0000000000000000000000000000000000000000..4fa21b22d4e150cb3c91f83b93acf3563342551c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/cmsis_5410x_m0.h @@ -0,0 +1,155 @@ +/* + * @brief Basic CMSIS include file for LPC5410x M0+ core + * + * @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 __CMSIS_5410X_M0_H_ +#define __CMSIS_5410X_M0_H_ + +#include "lpc_types.h" +#include "sys_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CMSIS_5410X_M0 CHIP: LPC5410X M0 core CMSIS include file + * @ingroup CHIP_5410X_CMSIS_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 + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +#if !defined(CORE_M0PLUS) +#error "CORE_M0PLUS is not defined" +#endif + +/** @defgroup CMSIS_5410X_M0_IRQ CHIP_5410X: LPC5410X M0 core peripheral interrupt numbers + * @{ + */ + +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 */ + + /****** LPC5410X Specific Interrupt Numbers ********************************************************/ + WDT_IRQn = 0, /*!< WWDT */ + BOD_IRQn = 1, /*!< BOD */ + Reserved2_IRQn = 2, /*!< Reserved Interrupt */ + DMA_IRQn = 3, /*!< DMA */ + GINT0_IRQn = 4, /*!< GINT0 */ + PIN_INT0_IRQn = 5, /*!< PININT0 */ + PIN_INT1_IRQn = 6, /*!< PININT1 */ + PIN_INT2_IRQn = 7, /*!< PININT2 */ + PIN_INT3_IRQn = 8, /*!< PININT3 */ + UTICK_IRQn = 9, /*!< Micro-tick Timer interrupt */ + MRT_IRQn = 10, /*!< Multi-rate timer interrupt */ + CT32B0_IRQn = 11, /*!< CTMR0 */ + CT32B1_IRQn = 12, /*!< CTMR1 */ + CT32B2_IRQn = 13, /*!< CTMR2 */ + CT32B3_IRQn = 14, /*!< CTMR3 */ + CT32B4_IRQn = 15, /*!< CTMR4 */ + SCT0_IRQn = 16, /*!< SCT */ + UART0_IRQn = 17, /*!< UART0 */ + UART1_IRQn = 18, /*!< UART1 */ + UART2_IRQn = 19, /*!< UART2 */ + UART3_IRQn = 20, /*!< UART3 */ + I2C0_IRQn = 21, /*!< I2C0 */ + I2C1_IRQn = 22, /*!< I2C1 */ + I2C2_IRQn = 23, /*!< I2C2 */ + SPI0_IRQn = 24, /*!< SPI0 */ + SPI1_IRQn = 25, /*!< SPI1 */ + ADC_SEQA_IRQn = 26, /*!< ADC0 sequence A completion */ + ADC_SEQB_IRQn = 27, /*!< ADC0 sequence B completion */ + ADC_THCMP_IRQn = 28, /*!< ADC0 threshold compare and error */ + RTC_IRQn = 29, /*!< RTC alarm and wake-up interrupts */ + Reserved30_IRQn = 30, /*!< Reserved Interrupt */ + MAILBOX_IRQn = 31, /*!< Mailbox */ +} LPC5410X_M0_IRQn_Type; + +/** + * @} + */ + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/** @defgroup CMSIS_5410X_M0_COMMON CHIP: LPC5410X M0 core Cortex CMSIS definitions + * @{ + */ + +/* Configuration of the Cortex-M0+ Processor and Core Peripherals */ +#define __CM0PLUS_REV 0x0001 /*!< Cortex-M0PLUS Core Revision */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#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 */ +#define __VTOR_PRESENT 1 + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_5410X_M0_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/sys_config.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/sys_config.h new file mode 100644 index 0000000000000000000000000000000000000000..0500ef091c3ae6d49c3ab90f22d9d3cb158ccb10 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/config/sys_config.h @@ -0,0 +1,43 @@ +/* + * @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 __SYS_CONFIG_H_ +#define __SYS_CONFIG_H_ + +/* Build for LPC5410X chip family */ +#define CHIP_LPC5410X + +/* Define ROMDRIVERSV2_PRESENT to enable v2 driver support in ROM. For LPC54xxx + devices with boot ROM version 17.2 and later, this should be defined. + For earlier versions, this should not be defined. If the definitions is + not defined, the same v2 drivers will be used, but will use a version that + is located in FLASH instead. */ +// #define ROMDRIVERSV2_PRESENT + +#endif /* __SYS_CONFIG_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cpuctrl_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cpuctrl_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..0e0dbd15c7ce8e4724ace152440a6d3cf3ff751e --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/cpuctrl_5410x.h @@ -0,0 +1,98 @@ +/* + * @brief LPC5410X CPU multi-core support 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 __CPUCTRL_5410X_H_ +#define __CPUCTRL_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CPUCTRL_5410X CHIP: LPC5410X CPU multi-core support driver + * @ingroup CHIP_5410X_DRIVERS + * This driver helps with determine which MCU core the software is running, + * whether the MCU core is in master or slave mode, and provides functions + * for master and slave core control.
+ * + * The functions for the driver are provided as part of the + * @ref POWER_LIBRARY_5410X library. For more information on using the + * LPC5410x LPCopen package with multi-core, see @ref CHIP_5410X_MULTICORE
. + * @{ + */ + +/** + * @brief Determine which MCU this code is running on + * @return true if executing on the CM4, or false if executing on the CM0+ + */ +STATIC INLINE bool Chip_CPU_IsM4Core(void) { + /* M4 core is designated by values 0xC24 on bits 15..4 */ + if (((SCB->CPUID >> 4) & 0xFFF) == 0xC24) { + return true; + } + + return false; +} + +/** + * @brief Determine if this core is a slave or master + * @return true if this MCU is operating as the master, or false if operating as a slave + */ +bool Chip_CPU_IsMasterCore(void); + +/** + * @brief Setup M0+ boot and reset M0+ core + * @param coentry : Pointer to boot entry point for M0+ core + * @param costackptr : Pointer to where stack should be located for M0+ core + * @return Nothing + * @note Will setup boot stack and entry point, enable M0+ clock and then + * reset M0+ core. + */ +void Chip_CPU_CM0Boot(uint32_t *coentry, uint32_t *costackptr); + +/** + * @brief Setup M4 boot and reset M4 core + * @param coentry : Pointer to boot entry point for M4 core + * @param costackptr : Pointer to where stack should be located for M4 core + * @return Nothing + * @note Will setup boot stack and entry point, enable M4 clock and then + * reset M0+ core. + */ +void Chip_CPU_CM4Boot(uint32_t *coentry, uint32_t *costackptr); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CPUCTRL_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..a4305a481a0ae0a37949b3e7deb387260f9d8dcc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.c @@ -0,0 +1,118 @@ +/* + * @brief LPC5410X Cyclic Redundancy Check (CRC) Engine 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize CRC engine */ +void Chip_CRC_Init(void) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_CRC); + Chip_SYSCON_PeriphReset(RESET_CRC); +} + +/* De-initialize CRC engine */ +void Chip_CRC_Deinit(void) +{ + Chip_Clock_DisablePeriphClock(SYSCON_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(); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..cbf5ac93b556f7f8f9889a7efaebcf4024fb5647 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/crc_5410x.h @@ -0,0 +1,262 @@ +/* + * @brief LPC5410X Cyclic Redundancy Check (CRC) Engine 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 __CRC_5410X_H_ +#define __CRC_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CRC_5410X CHIP: LPC5410X Cyclic Redundancy Check Engine driver + * @ingroup CHIP_5410X_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_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..fea37d9b5c438b702e3a60d5f3a52d81a82968bc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.c @@ -0,0 +1,306 @@ +/* + * @brief LPC5410X System FIFO chip 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 + ****************************************************************************/ + +/** SPI FIFO read FIFO statuses */ +#define LPC_SPIRXFIFO_STAT_SSEL0N (1 << 16) /*!< Slave select for receive on SSEL0 (active low) */ +#define LPC_SPIRXFIFO_STAT_SSEL1N (1 << 17) /*!< Slave select for receive on SSEL1 (active low) */ +#define LPC_SPIRXFIFO_STAT_SSEL2N (1 << 18) /*!< Slave select for receive on SSEL2 (active low) */ +#define LPC_SPIRXFIFO_STAT_SSEL3N (1 << 19) /*!< Slave select for receive on SSEL3 (active low) */ +#define LPC_SPIRXFIFO_STAT_SOT (1 << 20) /*!< This flag will be 1 if this is the first data after the SSELs went from deasserted to asserted */ + +/** SPI FIFO write FIFO control */ +#define LPC_SPITXFIFO_CTRL_SSEL0N (1 << 16) /*!< Master assert for receive on SSEL0 (active low) */ +#define LPC_SPITXFIFO_CTRL_SSEL1N (1 << 17) /*!< Master assert for receive on SSEL1 (active low) */ +#define LPC_SPITXFIFO_CTRL_SSEL2N (1 << 18) /*!< Master assert for receive on SSEL2 (active low) */ +#define LPC_SPITXFIFO_CTRL_SSEL3N (1 << 19) /*!< Master assert for receive on SSEL3 (active low) */ +#define LPC_SPITXFIFO_CTRL_EOT (1 << 20) /*!< End of Transfer. The asserted SSEL will be deasserted at the end of a transfer */ +#define LPC_SPITXFIFO_CTRL_EOF (1 << 21) /*!< End of Frame. Between frames, a delay may be inserted, as defined by the FRAME_DELAY value in the DLY register */ +#define LPC_SPITXFIFO_CTRL_RXIGNORE (1 << 22) /*!< Receive Ignore. This allows data to be transmitted using the SPI without the need to read unneeded data from the receiver */ +#define LPC_SPITXFIFO_CTRL_LEN(n) ((n) << 24) /*!< Data Length. Specifies the data length from 1 to 16 bits ((n-1) encoded) */ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initializes the system FIFO */ +void Chip_FIFO_Init(LPC_FIFO_T *pFIFO) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_FIFO); + Chip_SYSCON_PeriphReset(RESET_FIFO); +} + +/* Deinitializes the system FIFO */ +void Chip_FIFO_Deinit(LPC_FIFO_T *pFIFO) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_FIFO); +} + +/* Get the FIFO space available for the USART/SPI direction */ +uint32_t Chip_FIFO_GetFifoSpace(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir) +{ + uint32_t pcfg; + + if (periphId == FIFO_USART) { + pcfg = pFIFO->common.FIFOCTLUSART; + } + else { + pcfg = pFIFO->common.FIFOCTLSPI; + } + + if (dir == FIFO_RX) { + pcfg = pcfg >> 16; + } + else { + pcfg = pcfg >> 24; + } + + return pcfg & 0xFF; +} + +/* Pause a peripheral FIFO */ +void Chip_FIFO_PauseFifo(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir) +{ + if (periphId == FIFO_USART) { + if (dir == FIFO_RX) { + pFIFO->common.FIFOCTLUSART |= (1 << 0); + } + else { + pFIFO->common.FIFOCTLUSART |= (1 << 8); + } + } + else { + if (dir == FIFO_RX) { + pFIFO->common.FIFOCTLSPI |= (1 << 0); + } + else { + pFIFO->common.FIFOCTLSPI |= (1 << 8); + } + } +} + +/* Unpause a peripheral FIFO */ +void Chip_FIFO_UnpauseFifo(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir) +{ + if (periphId == FIFO_USART) { + if (dir == FIFO_RX) { + pFIFO->common.FIFOCTLUSART &= ~(1 << 0); + } + else { + pFIFO->common.FIFOCTLUSART &= ~(1 << 8); + } + } + else { + if (dir == FIFO_RX) { + pFIFO->common.FIFOCTLSPI &= ~(1 << 0); + } + else { + pFIFO->common.FIFOCTLSPI &= ~(1 << 8); + } + } +} + +/* Configure a peripheral's FIFO sizes */ +void Chip_FIFO_ConfigFifoSize(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_CFGSIZE_T *pSizes) +{ + int maxP, i; + uint32_t upDateMask; + volatile uint32_t *updateReg, *pFifoSizes, *pFifoPause; + + /* Pause FIFOs */ + Chip_FIFO_PauseFifo(LPC_FIFO, periphId, FIFO_RX); + Chip_FIFO_PauseFifo(LPC_FIFO, periphId, FIFO_TX); + + /* Maximum peripheral FIFOs supported */ + if (periphId == FIFO_USART) { + maxP = LPC_FIFO_USART_MAX; + updateReg = &pFIFO->common.FIFOUPDATEUSART; + upDateMask = 0xF | (0xF << 16); + pFifoSizes = &pFIFO->common.FIFOCFGUSART[0]; + pFifoPause = &pFIFO->common.FIFOCTLUSART; + } + else { + maxP = LPC_FIFO_SPI_MAX; + updateReg = &pFIFO->common.FIFOUPDATESPI; + upDateMask = 0x3 | (0x3 << 16); + pFifoSizes = &pFIFO->common.FIFOCFGSPI[0]; + pFifoPause = &pFIFO->common.FIFOCTLSPI; + } + + /* Wait for FIFO pause */ + while ((*pFifoPause & ((1 << 0) | (1 << 8))) != ((1 << 0) | (1 << 8))) {} + + /* Update FIFO sizes */ + for (i = 0; i < maxP; i++) { + pFifoSizes[i] = ((uint32_t) (pSizes->fifoRXSize[i]) << 0) | + ((uint32_t) (pSizes->fifoTXSize[i]) << 8); + } + + /* Update all peripheral FIFO sizes */ + *updateReg = upDateMask; +} + +/* Configure the USART system FIFO */ +void Chip_FIFOUSART_Configure(LPC_FIFO_T *pFIFO, int usartIndex, LPC_FIFO_CFG_T *pUSARTCfg) +{ + pFIFO->usart[usartIndex].CFG = + (pUSARTCfg->noTimeoutContWrite << 4) | + (pUSARTCfg->noTimeoutContEmpty << 5) | + (pUSARTCfg->timeoutBase << 8) | + (pUSARTCfg->timeoutValue << 12) | + (pUSARTCfg->rxThreshold << 16) | + (pUSARTCfg->txThreshold << 24); +} + +/* Write data to a system FIFO (non-blocking) */ +int Chip_FIFOUSART_WriteTX(LPC_FIFO_T *pFIFO, int usartIndex, bool sz8, void *buff, int numData) +{ + int datumWritten, sz16; + uint8_t *p8 = (uint8_t *) buff; + uint16_t *p16 = (uint16_t *) buff; + + /* Get configured FIFO size to determine write size, limit to buffer size */ + sz16 = (pFIFO->usart[usartIndex].STAT >> 24) & 0xFF; + if (sz16 > numData) { + sz16 = numData; + } + datumWritten = sz16; + + /* Write from buffer */ + while (sz16 > 0) { + if (sz8) { + pFIFO->usart[usartIndex].TXDAT = (uint32_t) *p8; + p8++; + } + else { + pFIFO->usart[usartIndex].TXDAT = (uint32_t) *p16; + p16++; + } + + sz16--; + } + + return datumWritten; +} + +/* Read data from a system FIFO (non-blocking) */ +int Chip_FIFOUSART_ReadRX(LPC_FIFO_T *pFIFO, int usartIndex, bool sz8, void *buff, int numData) +{ + int datumRead, sz16; + uint8_t *p8 = (uint8_t *) buff; + uint16_t *p16 = (uint16_t *) buff; + + /* Get configured FIFO size to determine read size, limit to buffer size */ + sz16 = (pFIFO->usart[usartIndex].STAT >> 16) & 0xFF; + if (sz16 > numData) { + sz16 = numData; + } + datumRead = sz16; + + /* Read into buffer */ + while (sz16 > 0) { + if (sz8) { + *p8 = (uint8_t) (pFIFO->usart[usartIndex].RXDAT & 0xFF); + p8++; + } + else { + *p16 = (uint16_t) (pFIFO->usart[usartIndex].RXDAT & 0x1FF); + p16++; + } + + sz16--; + } + + return datumRead; +} + +/* Read data from a system FIFO with status (non-blocking) */ +int Chip_FIFOUSART_ReadRXStatus(LPC_FIFO_T *pFIFO, int usartIndex, uint16_t *buff, int numData) +{ + int datumRead, sz16; + uint16_t *p16 = (uint16_t *) buff; + + /* Get configured FIFO size to determine read size, limit to buffer size */ + sz16 = (pFIFO->usart[usartIndex].STAT >> 16) & 0xFF; + if (sz16 > numData) { + sz16 = numData; + } + datumRead = sz16; + + /* Read into buffer */ + while (sz16 > 0) { + *p16 = (uint16_t) (pFIFO->usart[usartIndex].RXDATSTAT & 0xFFFF); + p16++; + sz16--; + } + + return datumRead; +} + +#if 0 /* Sorry, not yet support */ +/* Configure the USART system FIFO */ +void Chip_FIFOSPI_Configure(LPC_FIFO_T *pFIFO, int spiIndex, LPC_FIFO_CFG_T *pSPICfg) +{ + pFIFO->spi[spiIndex].CFG = + (pSPICfg->noTimeoutContWrite << 4) | + (pSPICfg->noTimeoutContEmpty << 5) | + (pSPICfg->timeoutBase << 6) | + (pSPICfg->timeoutValue << 12) | + (pSPICfg->rxThreshold << 16) | + (pSPICfg->txThreshold << 24); +} + +/* Start a data transfer (non-blocking) */ +void Chip_FIFOSPI_StartTransfer(LPC_FIFO_T *pFIFO, LPC_FIFO_SPICTL_T *pSetupData) +{ + pSetupData->start = 1; + Chip_FIFOSPI_Transfer(pFIFO, pSetupData); +} + + +/* Feed a SPI data transfer (non-blocking) */ +void Chip_FIFOSPI_Transfer(LPC_FIFO_T *pFIFO, LPC_FIFO_SPICTL_T *pSetupData) +{ + // FIXME - not yet ready +} +#endif diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..2c8f48878cbcbdb92cca4dcf3d838a463121289a --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/fifo_5410x.h @@ -0,0 +1,558 @@ +/* + * @brief LPC5410X System FIFO chip 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 __FIFO_5410X_H_ +#define __FIFO_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup FIFO_5410X CHIP: LPC5410X System FIFO chip driver + * @ingroup CHIP_5410X_DRIVERS + * This driver provides basic functionality for the system FIFO + * and can be used to increase the amount of FIFO space available + * to the UART and SPI peripherals. If using the system FIFO with the + * UART or SPI drivers, the standard UART and SPI transfer handlers + * cannot be used and buffer/stream management and status checking + * must occur in the user application. + * @{ + */ + +/** Maximum USART peripherals */ +#define LPC_FIFO_USART_MAX (4) + +/** Maximum SPI peripherals */ +#define LPC_FIFO_SPI_MAX (2) + +/** + * @brief LPC5410X System FIFO USART register block structure + */ +typedef struct { + __IO uint32_t CFG; /*!< USART configuration Register */ + __IO uint32_t STAT; /*!< USART status Register */ + __IO uint32_t INTSTAT; /*!< USART interrupt status Register */ + __IO uint32_t CTLSET; /*!< USART control read and set Register */ + __IO uint32_t CTLCLR; /*!< USART control clear Register */ + __IO uint32_t RXDAT; /*!< USART received data Register */ + __IO uint32_t RXDATSTAT; /*!< USART received data with status Register */ + __IO uint32_t TXDAT; /*!< USART transmit data Register */ + __I uint32_t RESERVED[0x38]; +} LPC_FIFO_USART_T; + +/** + * @brief LPC5410X System FIFO SPI register block structure + */ +typedef struct { + __IO uint32_t CFG; /*!< SPI configuration Register */ + __IO uint32_t STAT; /*!< SPI status Register */ + __IO uint32_t INTSTAT; /*!< SPI interrupt status Register */ + __IO uint32_t CTLSET; /*!< SPI control read and set Register */ + __IO uint32_t CTLCLR; /*!< SPI control clear Register */ + __I uint32_t RXDAT; /*!< SPI received data Register */ + union { + __O uint32_t TXDATSPI; /*!< SPI transmit data and control Register */ + struct { + __O uint16_t TXDATSPI_DATA; /*!< SPI transmit data Register */ + __O uint16_t TXDATSPI_CTRL; /*!< SPI transmit control Register */ + }; + + }; + + __I uint32_t RESERVED[0x39]; +} LPC_FIFO_SPI_T; + +/** + * @brief LPC5410X System FIFO common register block structure + */ +typedef struct { + __I uint32_t reserved0[0x40]; + __IO uint32_t FIFOCTLUSART; /*!< USART FIFO global control Register */ + __O uint32_t FIFOUPDATEUSART; /*!< USART FIFO global update Register */ + __I uint32_t reserved1[0x2]; + __IO uint32_t FIFOCFGUSART[LPC_FIFO_USART_MAX]; /*!< USART FIFO configuration Registers */ + __I uint32_t reserved2[0x38]; + __IO uint32_t FIFOCTLSPI; /*!< SPI FIFO global control Register */ + __O uint32_t FIFOUPDATESPI; /*!< SPI FIFO global update Register */ + __I uint32_t reserved3[0x2]; + __IO uint32_t FIFOCFGSPI[LPC_FIFO_SPI_MAX]; /*!< SPI FIFO configuration Registers */ + __I uint32_t reserved4[0x3A]; + __I uint32_t reserved5[((0x1000 - 0x300) / sizeof(uint32_t))]; +} LPC_FIFO_CMN_T; + +/** + * @brief LPC5410X Complete system FIFO register block structure + */ +typedef struct { + LPC_FIFO_CMN_T common; + LPC_FIFO_USART_T usart[LPC_FIFO_USART_MAX]; + __I uint32_t reserved0[((0x2000 - 0x1400) / sizeof(uint32_t))]; + LPC_FIFO_SPI_T spi[LPC_FIFO_SPI_MAX]; +} LPC_FIFO_T; + +/** @defgroup FIFO_CMN_5410X CHIP: Common FIFO functions + * These functions are for both the USART and SPI configuration and + * status. + * @{ + */ + +/** + * @brief Initializes the system FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @return Nothing + */ +void Chip_FIFO_Init(LPC_FIFO_T *pFIFO); + +/** + * @brief Deinitializes the system FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @return Nothing + */ +void Chip_FIFO_Deinit(LPC_FIFO_T *pFIFO); + +/** USART/SPI peripheral identifier */ +typedef enum {FIFO_USART, FIFO_SPI} LPC_FIFO_PERIPHID_T; + +/** USART/SPI FIFO direction identifier */ +typedef enum {FIFO_RX, FIFO_TX} LPC_FIFO_DIR_T; + +/** + * @brief Get the FIFO space available for the USART/SPI direction + * @brief pFIFO : Pointer to system FIFO registers + * @brief periphId : Peripheral identifer + * @brief dir : FIFO direction + * @return Amount of FIFO space available for the peripheral + */ +uint32_t Chip_FIFO_GetFifoSpace(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir); + +/** USART and SPI FIFO common statuses */ +#define LPC_FIFO_STAT_RXPAUSED (1 << 1) /*!< Receive FIFOs paused status */ +#define LPC_FIFO_STAT_RXEMPTY (1 << 2) /*!< Receive FIFOs empty status */ +#define LPC_FIFO_STAT_TXPAUSED (1 << 9) /*!< Transmit FIFOs paused status */ +#define LPC_FIFO_STAT_TXEMPTY (1 << 10) /*!< Transmit FIFOs empty status */ + +/** + * @brief Get periperhal FIFO status + * @brief pFIFO : Pointer to system FIFO registers + * @return A bitfield of status values, mask with LPC_FIFO_STAT_* values + * @note Mask with one or more LPC_FIFO_STAT_* definitions to get the + * status of the peripherals. + */ +STATIC INLINE uint32_t Chip_FIFO_GetFifoStatus(LPC_FIFO_T *pFIFO) +{ + return pFIFO->common.FIFOCTLUSART; +} + +/** + * @brief Pause a peripheral FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @brief periphId : Peripheral identifer + * @brief dir : FIFO direction + * @return Nothing + */ +void Chip_FIFO_PauseFifo(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir); + +/** + * @brief Unpause a peripheral FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @brief periphId : Peripheral identifer + * @brief dir : FIFO direction + * @return Nothing + */ +void Chip_FIFO_UnpauseFifo(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_DIR_T dir); + +/** Stucture for setting USART or SPI FIFO sizes */ +typedef struct { + uint16_t fifoRXSize[4]; /*!< FIFO RX size, 0-3 for USARTS 0-3, or 0-1 for SPIS 0-1 */ + uint16_t fifoTXSize[4]; /*!< FIFO TX size, 0-3 for USARTS 0-3, or 0-1 for SPIS 0-1 */ +} LPC_FIFO_CFGSIZE_T; + +/** + * @brief Configure a peripheral's FIFO sizes + * @brief pFIFO : Pointer to system FIFO registers + * @brief periphId : Peripheral identifer + * @brief pSizes : Pointer to s structure filled out with the peripherla FIFO sizes + * @return Nothing + * @note This function configures all the FIFOs for a supported peripheral + * in a single call. Use 0 to disable the FIFO. This function will pause the FIFO + * and leave it paused after configuration, call Chip_FIFO_UnpauseFifo() after + * calling this function. + */ +void Chip_FIFO_ConfigFifoSize(LPC_FIFO_T *pFIFO, LPC_FIFO_PERIPHID_T periphId, LPC_FIFO_CFGSIZE_T *pSizes); + +/** Stucture for setting USART and SPI FIFO configuration */ +typedef struct { + uint32_t noTimeoutContWrite : 1; /*!< Timeout Continue On Write, set to 0 to reset timeout on each TX FIFO data, or 1 for accumulated timeout */ + uint32_t noTimeoutContEmpty : 1; /*!< Timeout Continue On Empty., set to 0 to reset timeout on each RX FIFO data, or 1 for accumulated timeout */ + uint32_t timeoutBase : 4; /*!< Specifies the least significant timer bit to compare to TimeoutValue. See User Manual */ + uint32_t timeoutValue : 4; /*!< Specifies the maximum time value for timeout at the timer position identified by TimeoutBase. See User Manual */ + uint32_t rxThreshold : 8; /*!< Receive FIFO Threshold, number of data to receive prior to interrupt */ + uint32_t txThreshold : 8; /*!< Transmit FIFO Threshold, number of free TX data entries available prior to interrupt */ +} LPC_FIFO_CFG_T; + +/** USART and SPI FIFO statuses */ +#define LPC_PERIPFIFO_STAT_RXTH (1 << 0) /*!< When 1, the receive FIFO threshold has been reached */ +#define LPC_PERIPFIFO_STAT_TXTH (1 << 1) /*!< When 1, the transmit FIFO threshold has been reached */ +#define LPC_PERIPFIFO_STATCLR_RXTIMEOUT (1 << 4) /*!< When 1, the receive FIFO has timed out, based on the timeout configuration in the CFG register */ +#define LPC_PERIPFIFO_STATCLR_BUSERR (1 << 7) /*!< Bus Error. When 1, a bus error has occurred while processing data for the peripheral. The bus error flag can be cleared by writing a 1 to this bit. */ +#define LPC_PERIPFIFO_STAT_RXEMPTY (1 << 8) /*!< Receive FIFO Empty. When 1, the receive FIFO is currently empty. */ +#define LPC_PERIPFIFO_STAT_TXEMPTY (1 << 9) /*!< Transmit FIFO Empty. When 1, the transmit FIFO is currently empty. */ + +/** USART interrupt enable/disable bits */ +#define LPC_PERIPFIFO_INT_RXTH (1 << 0) /*!< Receive FIFO Threshold Interrupt Enable */ +#define LPC_PERIPFIFO_INT_TXTH (1 << 1) /*!< Transmit FIFO Threshold Interrupt Enable */ +#define LPC_PERIPFIFO_INT_RXTIMEOUT (1 << 4) /*!< Receive FIFO Timeout Interrupt Enable */ +#define LPC_PERIPFIFO_INT_RXFLUSH (1 << 8) /*!< Receive FIFO flush */ +#define LPC_PERIPFIFO_INT_TXFLUSH (1 << 9) /*!< Transmit FIFO flush */ + +/** + * @} + */ + +/** @defgroup FIFO_USART_5410X CHIP: USART FIFO functions + * These functions are for both the USART configuration, control, and status. + * @{ + */ + +/** + * @brief Configure the USART system FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief pUSARTCfg : Pointer to USART configuration + * @return Nothing + */ +void Chip_FIFOUSART_Configure(LPC_FIFO_T *pFIFO, int usartIndex, LPC_FIFO_CFG_T *pUSARTCfg); + +/** + * @brief Get USART FIFO statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @return USART system FIFO statuses (mask with LPC_PERIPFIFO_STAT* values) + */ +STATIC INLINE uint32_t Chip_FIFOUSART_GetStatus(LPC_FIFO_T *pFIFO, int usartIndex) +{ + return pFIFO->usart[usartIndex].STAT; +} + +/** + * @brief Get USART RX FIFO count + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @return Returns how many entries may be read from the receive FIFO. 0 = FIFO empty. + */ +STATIC INLINE uint32_t Chip_FIFOUSART_GetRxCount(LPC_FIFO_T *pFIFO, int usartIndex) +{ + return (pFIFO->usart[usartIndex].STAT >> 16) & 0xFF; +} + +/** + * @brief Get USART TC FIFO count + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @return Returns how many entries may be written to the transmit FIFO. 0 = FIFO full. + */ +STATIC INLINE uint32_t Chip_FIFOUSART_GetTxCount(LPC_FIFO_T *pFIFO, int usartIndex) +{ + return (pFIFO->usart[usartIndex].STAT >> 24) & 0xFF; +} + +/** + * @brief Clear USART FIFO statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief clearMask : Mask of latched bits to cleared, Or'ed values of LPC_PERIPFIFO_STATCLR* + * @return Nothing + */ +STATIC INLINE void Chip_FIFOUSART_ClearStatus(LPC_FIFO_T *pFIFO, int usartIndex, uint32_t clearMask) +{ + pFIFO->usart[usartIndex].STAT = clearMask; +} + +/** + * @brief Get USART FIFO pending interrupt statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @return USART system FIFO pending interrupt statuses (mask with LPC_PERIPFIFO_STAT* values) + */ +STATIC INLINE uint32_t Chip_FIFOUSART_GetIntStatus(LPC_FIFO_T *pFIFO, int usartIndex) +{ + return pFIFO->usart[usartIndex].INTSTAT; +} + +/** + * @brief Enable USART system FIFO interrupts + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief intMask : Interrupts to enable (LPC_PERIPFIFO_INT_RXTH, LPC_PERIPFIFO_INT_TXTH, or LPC_PERIPFIFO_INT_RXTIMEOUT) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOUSART_EnableInts(LPC_FIFO_T *pFIFO, int usartIndex, uint32_t intMask) +{ + pFIFO->usart[usartIndex].CTLSET = intMask; +} + +/** + * @brief Disable USART system FIFO interrupts + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief intMask : Interrupts to disable (LPC_PERIPFIFO_INT_RXTH, LPC_PERIPFIFO_INT_TXTH, or LPC_PERIPFIFO_INT_RXTIMEOUT) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOUSART_DisableInts(LPC_FIFO_T *pFIFO, int usartIndex, uint32_t intMask) +{ + pFIFO->usart[usartIndex].CTLCLR = intMask; +} + +/** + * @brief Flush TX and/or RX USART system FIFOs + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief flushMask : FIFOS to flush (Or'ed LPC_PERIPFIFO_INT_RXFLUSH and/or LPC_PERIPFIFO_INT_TXFLUSH) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOUSART_FlushFIFO(LPC_FIFO_T *pFIFO, int usartIndex, uint32_t flushMask) +{ + flushMask = flushMask & (LPC_PERIPFIFO_INT_RXFLUSH | LPC_PERIPFIFO_INT_TXFLUSH); + + pFIFO->usart[usartIndex].CTLSET = flushMask; + pFIFO->usart[usartIndex].CTLCLR = flushMask; +} + +/** + * @brief Write data to a USART system FIFO (non-blocking) + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief sz8 : Set to true for 8-bit or less data, or false for >8-bit + * @brief buff : Pointer to data in buffer to write + * @brief numData : Maximum number of data values to write + * @return The number of data values written to the USART system FIFO + */ +int Chip_FIFOUSART_WriteTX(LPC_FIFO_T *pFIFO, int usartIndex, bool sz8, void *buff, int numData); + +/** + * @brief Read data from a USART system FIFO (non-blocking) + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief sz8 : Set to true for 8-bit or less data, or false for >8-bit + * @brief buff : Pointer to data buffer to read into + * @brief numData : Maximum number of data values to read + * @return The number of data values read from the USART system FIFO + */ +int Chip_FIFOUSART_ReadRX(LPC_FIFO_T *pFIFO, int usartIndex, bool sz8, void *buff, int numData); + +/** USART FIFO read FIFO statuses */ +#define LPC_USARTRXFIFO_STAT_FRAMERR (1 << 13) /*!< Framing Error status flag */ +#define LPC_USARTRXFIFO_STAT_PARITYERR (1 << 14) /*!< Parity Error status flag */ +#define LPC_USARTRXFIFO_STAT_RXNOISE (1 << 15) /*!< Received Noise flag */ + +/** + * @brief Read data from a USART system FIFO with status (non-blocking) + * @brief pFIFO : Pointer to system FIFO registers + * @brief usartIndex : USART system FIFO index, 0 - 3 + * @brief buff : Pointer to data buffer to read into + * @brief numData : Maximum number of data values to read + * @return The number of data values with status read from the USART system FIFO. Mask + * the upper bits of each word in the buffer with the LPC_USARTRXFIFO_STAT_* flags to + * determine individual data status. + */ +int Chip_FIFOUSART_ReadRXStatus(LPC_FIFO_T *pFIFO, int usartIndex, uint16_t *buff, int numData); + +/** + * @} + */ + +/** @defgroup FIFO_SPI_5410X CHIP: SPI FIFO functions + * These functions are for both the SPI configuration, control, and status. + * @{ + */ + +/** + * @brief Configure the SPI system FIFO + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @brief pUSARTCfg : Pointer to SPI configuration + * @return Nothing + */ +void Chip_FIFOSPI_Configure(LPC_FIFO_T *pFIFO, int spiIndex, LPC_FIFO_CFG_T *pSPICfg); + +/** + * @brief Get SPI FIFO statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @return SPI system FIFO statuses (mask with LPC_PERIPFIFO_STAT* values) + */ +STATIC INLINE uint32_t Chip_FIFOSPI_GetStatus(LPC_FIFO_T *pFIFO, int spiIndex) +{ + return pFIFO->spi[spiIndex].STAT; +} + +/** + * @brief Get SPI RX FIFO count + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @return Returns how many entries may be read from the receive FIFO. 0 = FIFO empty. + */ +STATIC INLINE uint32_t Chip_FIFOSPI_GetRxCount(LPC_FIFO_T *pFIFO, int spiIndex) +{ + return (pFIFO->spi[spiIndex].STAT >> 16) & 0xFF; +} + +/** + * @brief Get SPI TX FIFO count + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @return Returns how many entries may be written to the transmit FIFO. 0 = FIFO full. + */ +STATIC INLINE uint32_t Chip_FIFOSPI_GetTxCount(LPC_FIFO_T *pFIFO, int spiIndex) +{ + return (pFIFO->spi[spiIndex].STAT >> 24) & 0xFF; +} + +/** + * @brief Clear SPI FIFO statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @brief clearMask : Mask of latched bits to cleared, Or'ed values of LPC_PERIPFIFO_STATCLR* + * @return Nothing + */ +STATIC INLINE void Chip_FIFOSPI_ClearStatus(LPC_FIFO_T *pFIFO, int spiIndex, uint32_t clearMask) +{ + pFIFO->spi[spiIndex].STAT = clearMask; +} + +/** + * @brief Get SPI FIFO pending interrupt statuses + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @return SPI system FIFO pending interrupt statuses (mask with LPC_PERIPFIFO_STAT* values) + */ +STATIC INLINE uint32_t Chip_FIFOSPI_GetIntStatus(LPC_FIFO_T *pFIFO, int spiIndex) +{ + return pFIFO->spi[spiIndex].INTSTAT; +} + +/** + * @brief Enable SPI system FIFO interrupts + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @brief intMask : Interrupts to enable (LPC_PERIPFIFO_INT_RXTH, LPC_PERIPFIFO_INT_TXTH, or LPC_PERIPFIFO_INT_RXTIMEOUT) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOSPI_EnableInts(LPC_FIFO_T *pFIFO, int spiIndex, uint32_t intMask) +{ + pFIFO->spi[spiIndex].CTLSET = intMask; +} + +/** + * @brief Disable SPI system FIFO interrupts + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @brief intMask : Interrupts to disable (LPC_PERIPFIFO_INT_RXTH, LPC_PERIPFIFO_INT_TXTH, or LPC_PERIPFIFO_INT_RXTIMEOUT) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOSPI_DisableInts(LPC_FIFO_T *pFIFO, int spiIndex, uint32_t intMask) +{ + pFIFO->spi[spiIndex].CTLCLR = intMask; +} + +/** + * @brief Flush TX and/or RX SPI system FIFOs + * @brief pFIFO : Pointer to system FIFO registers + * @brief spiIndex : SPI system FIFO index, 0 - 1 + * @brief flushMask : FIFOS to flush (Or'ed LPC_PERIPFIFO_INT_RXFLUSH and/or LPC_PERIPFIFO_INT_TXFLUSH) + * @return Nothing + */ +STATIC INLINE void Chip_FIFOSPI_FlushFIFO(LPC_FIFO_T *pFIFO, int spiIndex, uint32_t flushMask) +{ + flushMask = flushMask & (LPC_PERIPFIFO_INT_RXFLUSH | LPC_PERIPFIFO_INT_TXFLUSH); + + pFIFO->spi[spiIndex].CTLSET = flushMask; + pFIFO->spi[spiIndex].CTLCLR = flushMask; +} + +/** SPI transfer flags */ +#define LPC_SPIFIFO_FLAG_EOF (1 << 21) /*!< Add a delay between frames */ +#define LPC_SPIFIFO_FLAG_RXIGNORE (1 << 22) /*!< Ignore RX data */ + +/** SPI transfer error statuses */ +#define LPC_SPIFIFO_STAT_BUSY (0x0) /*!< SPI transfer busy/in progress */ +#define LPC_SPIFIFO_STAT_BADPARAM (0x1) /*!< SPI paramaters for transfer are invalid */ +#define LPC_SPIFIFO_STAT_TXUNDERRUN (0x2) /*!< Slave mode only, transmit FIFO underrun */ +#define LPC_SPIFIFO_STAT_RXOVERRUN (0x3) /*!< Slave mode only, receive FIFO overrun */ +#define LPC_SPIFIFO_STAT_COMPLETE (0xF) /*!< SPI transfer completed successfully */ + +#if 0 /* Sorry, not yet support */ +/** Stucture for SPI control */ +typedef struct { + uint32_t start : 1; /*!< Indicates transfer start, 0 = transfer resume, 1 = transfer start (automatically set by Chip_FIFOSPI_StartTransfer()) */ + uint32_t end : 1; /*!< Transfer wil end once buffers are empty */ + uint32_t sz8 : 1; /*!< Specifies the in and out buffer sizes, 0 = 16-bit, 1 = 8-bit */ + uint32_t sselNum : 2; /*!< SPI chip select number, 0 - 3 */ + void *inBuff; /*!< SPI transfer in data buffer pointer */ + uint32_t inIndex; /*!< SPI transfer in buffer index */ + void *outBuff; /*!< SPI transfer out data buffer pointer */ + uint32_t outIndex; /*!< SPI transfer out buffer index */ + uint32_t numData; /*!< Size of data both the receive and transfer buffers */ + int spiIndex; /*!< SPI system FIFO index, 0 - 1 */ +} LPC_FIFO_SPICTL_T; + +/** + * @brief Start a SPI data transfer (non-blocking) + * @brief pFIFO : Pointer to system FIFO registers + * @brief pSetupData : Pointer to SPI transfer setup structure + * @return Nothing + * @note Simply calls Chip_FIFOSPI_Transfer() with pSetupData->start = 1. + */ +void Chip_FIFOSPI_StartTransfer(LPC_FIFO_T *pFIFO, LPC_FIFO_SPICTL_T *pSetupData); + +/** + * @brief Feed a SPI data transfer (non-blocking) + * @brief pFIFO : Pointer to system FIFO registers + * @brief pSetupData : Pointer to SPI transfer setup structure + * @return Nothing + * @note Continues SPI transfer usng the system FIFO. + */ +void Chip_FIFOSPI_Transfer(LPC_FIFO_T *pFIFO, LPC_FIFO_SPICTL_T *pSetupData); +#endif + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FIFO_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..c97d365e04500feaaa7301b0e04c89ef5a4cd3a3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.c @@ -0,0 +1,108 @@ +/* + * @brief LPC5410X GPIO 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* GPIO initilisation function */ +void Chip_GPIO_Init(LPC_GPIO_T *pGPIO) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO0); + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO1); + Chip_SYSCON_PeriphReset(RESET_GPIO0); + Chip_SYSCON_PeriphReset(RESET_GPIO1); +} + +/* GPIO deinitialisation function */ +void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_GPIO0); + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_GPIO1); +} + +/* Set GPIO direction for a single GPIO pin */ +void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting) +{ + if (setting) { + pGPIO->DIR[port] |= 1UL << pin; + } + else { + pGPIO->DIR[port] &= ~(1UL << pin); + } +} + +/* Set GPIO direction for a single GPIO pin */ +void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output) +{ + if (output) { + Chip_GPIO_SetPinDIROutput(pGPIO, port, pin); + } + else { + Chip_GPIO_SetPinDIRInput(pGPIO, port, pin); + } +} + +/* Set Direction for a GPIO port */ +void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out) +{ + if (out) { + pGPIO->DIR[portNum] |= bitValue; + } + else { + pGPIO->DIR[portNum] &= ~bitValue; + } +} + +/* Set GPIO direction for a all selected GPIO pins to an input or output */ +void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask, bool outSet) +{ + if (outSet) { + Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask); + } + else { + Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask); + } +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..2522fe85affc683268ce6b5c6db5da0c7e11122d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpio_5410x.h @@ -0,0 +1,471 @@ +/* + * @brief LPC5410X GPIO 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 __GPIO_5410X_H_ +#define __GPIO_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup GPIO_5410X CHIP: LPC5410X GPIO driver + * @ingroup CHIP_5410X_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 */ +} LPC_GPIO_T; + +/** + * @brief Initialize GPIO block + * @param pGPIO : The base of GPIO peripheral on the chip + * @return Nothing + */ +void Chip_GPIO_Init(LPC_GPIO_T *pGPIO); + +/** + * @brief De-Initialize GPIO block + * @param pGPIO : The base of GPIO peripheral on the chip + * @return Nothing + */ +void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO); + +/** + * @brief Set a GPIO port/pin state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to set + * @param pin : GPIO pin to set + * @param setting : true for high, false for low + * @return Nothing + * @note It is recommended to use the Chip_GPIO_SetPinState() function instead. + */ +STATIC INLINE void Chip_GPIO_WritePortBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting) +{ + pGPIO->B[port][pin] = setting; +} + +/** + * @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 + * @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_SetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool setting) +{ + pGPIO->B[port][pin] = setting; +} + +/** + * @brief Read 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 + * @param pin : GPIO pin to read + * @return true if the GPIO pin is high, false if low + * @note It is recommended to use the Chip_GPIO_GetPinState() function instead. + */ +STATIC INLINE bool Chip_GPIO_ReadPortBit(LPC_GPIO_T *pGPIO, uint32_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 + * @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_GetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + return (bool) pGPIO->B[port][pin]; +} + +/** + * @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 + * @param pin : GPIO pin to set + * @param setting : true for output, false for input + * @return Nothing + * @note It is recommended to use the Chip_GPIO_SetPinDIROutput(), + * Chip_GPIO_SetPinDIRInput() or Chip_GPIO_SetPinDIR() functions instead + * of this function. + */ +void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting); + +/** + * @brief Set GPIO direction for a single GPIO pin to an output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to set + * @param pin : GPIO pin to set direction on as output + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetPinDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->DIR[port] |= 1UL << pin; +} + +/** + * @brief Set GPIO direction for a single GPIO pin to an input + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to set + * @param pin : GPIO pin to set direction on as input + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetPinDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->DIR[port] &= ~(1UL << pin); +} + +/** + * @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 + * @param pin : GPIO pin to set direction for + * @param output : true for output, false for input + * @return Nothing + */ +void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output); + +/** + * @brief Read a GPIO direction (out or in) + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to read + * @param bit : GPIO bit direction to read + * @return true if the GPIO is an output, false if input + * @note It is recommended to use the Chip_GPIO_GetPinDIR() function instead. + */ +STATIC INLINE bool Chip_GPIO_ReadDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit) +{ + return (bool) (((pGPIO->DIR[port]) >> bit) & 1); +} + +/** + * @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_GetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + return Chip_GPIO_ReadDirBit(pGPIO, port, pin); +} + +/** + * @brief Set Direction for a GPIO port + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port Number + * @param bitValue : GPIO bit to set + * @param out : Direction value, 0 = input, !0 = output + * @return None + * @note Bits set to '0' are not altered. It is recommended to use the + * Chip_GPIO_SetPortDIR() function instead. + */ +void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out); + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @param pinMask : GPIO pin mask to set direction on as output (bits 0..b for pins 0..n) + * @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_SetPortDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask) +{ + pGPIO->DIR[port] |= pinMask; +} + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an input + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @param pinMask : GPIO pin mask to set direction on as input (bits 0..b for pins 0..n) + * @return Nothing + * @note Sets multiple GPIO pins to the input direction, each bit's position that is + * high sets the corresponding pin number for that bit to an input. + */ +STATIC INLINE void Chip_GPIO_SetPortDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask) +{ + pGPIO->DIR[port] &= ~pinMask; +} + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an input or output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @param pinMask : GPIO pin mask to set direction on (bits 0..b for pins 0..n) + * @param outSet : Direction value, false = set as inputs, true = set as outputs + * @return Nothing + * @note Sets multiple GPIO pins to the input direction, each bit's position that is + * high sets the corresponding pin number for that bit to an input. + */ +void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask, bool outSet); + +/** + * @brief Get GPIO direction for a all GPIO pins + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @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_GetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->DIR[port]; +} + +/** + * @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 + * @return Nothing + * @note Controls which bits corresponding to PIO0_n are active in the P0MPORT + * register (bit 0 = PIO0_0, bit 1 = PIO0_1, ..., bit 17 = PIO0_17). + */ +STATIC INLINE void Chip_GPIO_SetPortMask(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_SetPortMask() function. + */ +STATIC INLINE uint32_t Chip_GPIO_GetPortMask(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->MASK[port]; +} + +/** + * @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_SetPortValue(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_GetPortValue(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->PIN[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_SetMaskedPortValue(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_GetMaskedPortValue(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->MPIN[port]; +} + +/** + * @brief Set a GPIO port/bit to the high state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number (supports port 0 only) + * @param bitValue : bit(s) in the port 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. It is recommended to use the + * Chip_GPIO_SetPortOutHigh() function instead. + */ +STATIC INLINE void Chip_GPIO_SetValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue) +{ + pGPIO->SET[portNum] = bitValue; +} + +/** + * @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_SetPortOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->SET[port] = pins; +} + +/** + * @brief Set an individual GPIO output pin to the high state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number (supports port 0 only) + * @param pin : pin number (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_SetPinOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->SET[port] = (1 << pin); +} + +/** + * @brief Set a GPIO port/bit to the low state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number (support port 0 only) + * @param bitValue : bit(s) in the port 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. It is recommended to use the + * Chip_GPIO_SetPortOutLow() function instead. + */ +STATIC INLINE void Chip_GPIO_ClearValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue) +{ + pGPIO->CLR[portNum] = bitValue; +} + +/** + * @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_SetPortOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->CLR[port] = pins; +} + +/** + * @brief Set an individual GPIO output pin to the low state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number (supports port 0 only) + * @param pin : pin number (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_SetPinOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->CLR[port] = (1 << pin); +} + +/** + * @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_SetPortToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->NOT[port] = pins; +} + +/** + * @brief Toggle an individual GPIO output pin to the opposite state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number (supports port 0 only) + * @param pin : pin number (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_SetPinToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->NOT[port] = (1 << pin); +} + +/** + * @brief Read current bit states for the selected port + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number to read (supports port 0 only) + * @return Current value of GPIO port + * @note The current states of the bits for the port are read, regardless of + * whether the GPIO port bits are input or output. It is recommended to use the + * Chip_GPIO_GetPortValue() function instead. + */ +STATIC INLINE uint32_t Chip_GPIO_ReadValue(LPC_GPIO_T *pGPIO, uint8_t portNum) +{ + return pGPIO->PIN[portNum]; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIO_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..8fa7bb45d6aad21a3b3d82579030bec83e0613cc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.c @@ -0,0 +1,48 @@ +/* + * @brief LPC5410x GPIO group 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..11f781a7589070660e2290a477fd20153c99a9bc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/gpiogroup_5410x.h @@ -0,0 +1,223 @@ +/* + * @brief LPC5410x GPIO group 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 __GPIOGROUP_5410X_H_ +#define __GPIOGROUP_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup GPIOGP_5410X CHIP: LPC5410x GPIO group driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief GPIO grouped interrupt register block structure + */ +typedef struct { /*!< GPIO_GROUP_INTn Structure */ + __IO uint32_t CTRL; /*!< GPIO grouped interrupt control register */ + __I uint32_t RESERVED0[7]; + __IO uint32_t PORT_POL[8]; /*!< GPIO grouped interrupt port polarity register */ + __IO uint32_t PORT_ENA[8]; /*!< GPIO grouped interrupt port m enable register */ + uint32_t RESERVED1[4072]; +} LPC_GPIOGROUPINT_T; + +/** + * LPC5410x GPIO group bit definitions + */ +#define GPIOGR_INT (1 << 0) /*!< GPIO interrupt pending/clear bit */ +#define GPIOGR_COMB (1 << 1) /*!< GPIO interrupt OR(0)/AND(1) mode bit */ +#define GPIOGR_TRIG (1 << 2) /*!< GPIO interrupt edge(0)/level(1) mode bit */ + +/** + * @brief Initialize GPIO group interrupt block + * @param pGPIOGPINT : The base of GPIO group peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_GPIOGP_Init(LPC_GPIOGROUPINT_T *pGPIOGPINT) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GINT); + Chip_SYSCON_PeriphReset(RESET_GINT); +} + +/** + * @brief De-Initialize GPIO group interrupt block + * @param pGPIOGPINT : The base of GPIO group peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_GPIOGP_DeInit(LPC_GPIOGROUPINT_T *pGPIOGPINT) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_GINT); +} + +/** + * @brief Clear interrupt pending status for the selected group + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_ClearIntStatus(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL |= GPIOGR_INT; +} + +/** + * @brief Returns current GPIO group inetrrupt pending status + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return true if the group interrupt is pending, otherwise false. + */ +STATIC INLINE bool Chip_GPIOGP_GetIntStatus(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + return (bool) ((pGPIOGPINT[group].CTRL & GPIOGR_INT) != 0); +} + +/** + * @brief Selected GPIO group functionality for trigger on any pin in group (OR mode) + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectOrMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL &= ~(GPIOGR_COMB | GPIOGR_INT); +} + +/** + * @brief Selected GPIO group functionality for trigger on all matching pins in group (AND mode) + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectAndMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL = (pGPIOGPINT[group].CTRL & ~GPIOGR_INT) | GPIOGR_COMB; +} + +/** + * @brief Selected GPIO group functionality edge trigger mode + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectEdgeMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL &= ~(GPIOGR_TRIG | GPIOGR_INT); +} + +/** + * @brief Selected GPIO group functionality level trigger mode + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectLevelMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL = (pGPIOGPINT[group].CTRL & ~GPIOGR_INT) | GPIOGR_TRIG; +} + +/** + * @brief Set selected pins for the group and port to low level trigger + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to select for low level (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectLowLevel(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_POL[port] &= ~pinMask; +} + +/** + * @brief Set selected pins for the group and port to high level trigger + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to select for high level (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectHighLevel(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_POL[port] |= pinMask; +} + +/** + * @brief Disabled selected pins for the group interrupt + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to disable interrupt for (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + * @note Disabled pins do not contribute to the group interrupt. + */ +STATIC INLINE void Chip_GPIOGP_DisableGroupPins(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_ENA[port] &= ~pinMask; +} + +/** + * @brief Enable selected pins for the group interrupt + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to enable interrupt for (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + * @note Enabled pins contribute to the group interrupt. + */ +STATIC INLINE void Chip_GPIOGP_EnableGroupPins(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_ENA[port] |= pinMask; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIOGROUP_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..8cc8d4ef3e227ba70de22f9c8e57e3fb42deab99 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.c @@ -0,0 +1,568 @@ +/* + * @brief ADC ROM API declarations and functions + * + * @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 +#include "hw_adc_rom_api.h" + +/** @brief ADC ROM Driver Version */ +#define ADC_DRIVER_VERSION 0x0100 + +/* Internal defines */ +#define SEQ_A_MASK 0x7C0C5FFF +#define SEQ_B_MASK 0x5C0C5FFF +#define CTRL_MASK 0x00007F00 + +#define ADC_STATE_INACTIVE 0 +#define ADC_STATE_IDLE 1 +#define ADC_STATE_ACTIVE 2 + +/** @brief Channel flags offset */ +#define CB_THRES(ch) (1UL << (ch)) +#define CB_DATA(ch) (0x10000UL << (ch)) + +/* ADC Buffer management */ +typedef struct { + uint16_t *pCurr; /* ReceiveBuffer Pointer */ + size_t szCurr; /* Receive Count */ + uint16_t *pNext; /* Ring Buffer Pointer */ + size_t szNext; /* Receive Count */ + uint32_t idx; /* Current index */ + int32_t state; /* State of ADC */ +} ADC_BUFFER_T; + +/* ADC Driver internal data structure */ +typedef struct { + void *pUserData; /* Pointer to user data */ + ADC_REGS_T *pREGS; /* Pointer to Registers */ + uint32_t valSeq[2]; /* Stored SEQ A/B Values */ + ADC_BUFFER_T buffer[2]; /* Buffers to store converted data */ + uint32_t flags; /* flags */ + uint32_t regThrSel; /* Threshold flags */ + uint32_t regInt; /* Interrupt register */ + uint32_t flag1; /* Flags Extra */ + void(*cbTable[ADC_CBIDX_RESERVED]) (ADC_HANDLE_T, ADC_CBINDEX_T, void *); +} ADC_DRIVER_T; + +/* Prototype defines */ +static ErrorCode_t ADC_StopConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex); + +/* PRIVATE: Invoke a call back function */ +static void _ADC_InvokeCallback(ADC_DRIVER_T *pADC, ADC_CBINDEX_T idx, void *param) +{ + if (pADC->cbTable[idx]) { + pADC->cbTable[idx]((ADC_HANDLE_T) pADC, idx, param); + } +} + +/* PRIVATE: Extract, format data and store into user buffer */ +static ErrorCode_t _ADC_GetData(ADC_DRIVER_T *pADC, ADC_SEQ_INDEX_T seqIndex, uint32_t data) +{ + uint8_t ch = ADC_DR_CHANNEL(data); + ADC_BUFFER_T *buf = &pADC->buffer[seqIndex]; + uint16_t *pDat = &buf->pCurr[buf->idx++]; + + /* Ignore extra data */ + if (!buf->szCurr) { + return LPC_OK; + } + + /* If data is not vaild something is wrong! */ + if (!(data & ADC_SEQ_GDAT_DATAVALID)) { + return ERR_FAILED; + } + + data >>= 4; + if (!(pADC->flag1 & (1UL << ch))) { + data &= 0xFFF; + } + + *pDat = data; + /* Invoke the call back for single data read if enabled */ + if (pADC->flags & CB_DATA(ch)) { + _ADC_InvokeCallback(pADC, ADC_CHDATA, (void *) ((ch << 16) | data)); + } + return LPC_OK; +} + +/* PRIVATE: Reads data from the GDAT or DAT register based on mode of operation */ +static ErrorCode_t _ADC_ReadData(ADC_DRIVER_T *pADC, ADC_SEQ_INDEX_T seqIndex) +{ + ADC_REGS_T *pREGS = pADC->pREGS; + int i; + + /* Check if this is End-of-Seq or End-of-SingleConversion */ + if (!(pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_MODE_EOS)) { + return _ADC_GetData(pADC, seqIndex, pREGS->SEQ_GDAT[seqIndex]); + } + + /* Read channels having conversion data */ + for (i = 0; i < sizeof(pREGS->DAT) / sizeof(pREGS->DAT[0]); i++) { + if (pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_CHANSEL(i)) { + if (_ADC_GetData(pADC, seqIndex, pREGS->DAT[i]) != LPC_OK) { + return ERR_FAILED; + } + } + } + return LPC_OK; +} + +/* PRIVATE: Overflow handler */ +static ErrorCode_t _ADC_Handle_Overflow(ADC_DRIVER_T *pADC, uint32_t flag) +{ + _ADC_InvokeCallback(pADC, ADC_OVERFLOW, (void *) ((flag >> 12) & 0x3FFF)); + return LPC_OK; +} + +/* PRIVATE: ADC Sequence event handler function */ +static ErrorCode_t _ADC_Handler_Seq(ADC_DRIVER_T *pADC, ADC_SEQ_INDEX_T seqIndex) +{ + ADC_REGS_T *pREGS = pADC->pREGS; + ADC_BUFFER_T *buf = &pADC->buffer[seqIndex]; + uint32_t flag = pREGS->FLAGS; + uint32_t tmp; + + /* Check if overrun is enabled and got an overrun */ + tmp = flag & ADC_FLAGS_SEQN_OVRRUN_MASK(seqIndex); + + if (!(flag & ADC_FLAGS_SEQN_INT_MASK(seqIndex))) { + return ERR_ADC_INVALID_SEQUENCE; + } + + if (_ADC_ReadData(pADC, seqIndex) != LPC_OK) { + return ERR_FAILED; + } + + /* Handle the overflow */ + if (tmp) { + _ADC_Handle_Overflow(pADC, flag); + } + + /* Clear the interrupt if it is for EOS and not EOC */ + if (pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_MODE_EOS) { + pREGS->FLAGS = ADC_FLAGS_SEQN_INT_MASK(seqIndex); + } + + /* See if we are done with our buffer */ + if (buf->idx >= buf->szCurr) { + _ADC_InvokeCallback(pADC, (ADC_CBINDEX_T) (ADC_BUFFER_DONE + (ADC_CBINDEX_T)seqIndex), buf->pCurr); + if (!buf->pNext || !buf->szNext) { + buf->pCurr = 0; + buf->szCurr = 0; + + /* Nothing more to do stop the ADC */ + ADC_StopConversion(pADC, seqIndex); + return LPC_OK; + } + buf->pCurr = buf->pNext; + buf->szCurr = buf->szNext; + buf->pNext = 0; + buf->idx = buf->szNext = 0; + } + + /* If we are not in burst mode we must trigger next sample */ + if (!((pADC->valSeq[seqIndex] >> 12) & 0x1F) && !(pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_BURST)) { + pREGS->SEQ_CTRL[seqIndex] = pADC->valSeq[seqIndex]; + } + + return LPC_OK; +} + +/* PRIVATE: ADC sequence handler polling mode */ +static ErrorCode_t _ADC_Handler_SeqPoll(ADC_DRIVER_T *pADC, ADC_SEQ_INDEX_T seqIndex) +{ + ADC_REGS_T *pREGS = pADC->pREGS; + ErrorCode_t ret = LPC_OK; + + /* Poll as long as the sequence is enabled */ + while (pREGS->SEQ_CTRL[seqIndex] & ADC_SEQ_CTRL_SEQ_ENA) { + if (!(pREGS->FLAGS & ADC_FLAGS_SEQN_INT_MASK(seqIndex))) { + continue; + } + ret = _ADC_Handler_Seq(pADC, seqIndex); + if (ret != LPC_OK) { + break; + } + } + return ret; +} + +/* PRIVATE: Handler for Overflow event */ +static ErrorCode_t _ADC_Handler_Ovr(ADC_DRIVER_T *pADC) +{ + uint32_t flags = pADC->pREGS->FLAGS; + + /* Invoke Sequence handler to clear-out the data */ + if (flags & ADC_FLAGS_SEQA_OVRRUN_MASK) { + return _ADC_Handler_Seq(pADC, ADC_SEQ_A); + } + else if (flags & ADC_FLAGS_SEQB_OVRRUN_MASK) { + return _ADC_Handler_Seq(pADC, ADC_SEQ_B); + } + else { + return ERR_FAILED; + } +} + +/* PRIVATE: Threshold event handler */ +static ErrorCode_t _ADC_Handler_Thres(ADC_DRIVER_T *pADC) +{ + uint32_t flags = pADC->pREGS->FLAGS; + + if (!(flags & ADC_FLAGS_THCMP_INT_MASK)) { + return ERR_FAILED; + } + + flags &= 0xFFF; + + /* Clear out the interrupts */ + pADC->pREGS->FLAGS = flags; + _ADC_InvokeCallback(pADC, ADC_THRESHOLD, (void *) flags); + + return LPC_OK; +} + +/* EXPORTED API: Register a call-back function */ +ErrorCode_t ADC_RegisterCallback(ADC_HANDLE_T hADC, ADC_CBINDEX_T idx, void (*cb_func)(ADC_HANDLE_T, + ADC_CBINDEX_T, + void *)) +{ + if (idx < ADC_CBIDX_RESERVED) { + ((ADC_DRIVER_T *) hADC)->cbTable[idx] = cb_func; + } + else { + return ERR_ADC_PARAM; + } + return LPC_OK; +} + +/* EXPORTED API: ADC Initialization function */ +ADC_HANDLE_T ADC_Init(void *mem, uint32_t base_addr, void *args) +{ + ADC_DRIVER_T *pADC; + + /* Check if the memory is word aligned */ + if ((uint32_t) mem & 0x3) { + return NULL; + } + + /* Assign memory provided by application */ + pADC = (ADC_DRIVER_T *) mem; + memset(pADC, 0, sizeof(ADC_DRIVER_T)); + + /* Assign the base address */ + pADC->pREGS = (ADC_REGS_T *) base_addr; + pADC->pUserData = args; + + /* To be safe stop the ADC in case it is not stopped */ + pADC->pREGS->SEQ_CTRL[0] = 0x00; + pADC->pREGS->SEQ_CTRL[1] = 0x00; + + return (ADC_HANDLE_T) pADC; +} + +/* EXPORTED API: Setup the ADC threshold registers */ +void ADC_SetThreshold(ADC_HANDLE_T hADC, uint32_t valThres0, uint32_t valThres1) +{ + ADC_REGS_T *pREGS = ((ADC_DRIVER_T *) hADC)->pREGS; + pREGS->THR0_LOW = (valThres0 << ADC_THR_VAL_POS) & ADC_THR_VAL_MASK; + pREGS->THR1_LOW = (valThres1 << ADC_THR_VAL_POS) & ADC_THR_VAL_MASK; + valThres0 >>= 16; + valThres1 >>= 16; + pREGS->THR0_HIGH = (valThres0 << ADC_THR_VAL_POS) & ADC_THR_VAL_MASK; + pREGS->THR1_HIGH = (valThres1 << ADC_THR_VAL_POS) & ADC_THR_VAL_MASK; +} + +/* EXPORTED API: Calibrate the ADC */ +ErrorCode_t ADC_Calibrate(ADC_HANDLE_T handle, uint32_t sysclk_freq) +{ + ADC_REGS_T *pREGS = ((ADC_DRIVER_T *) handle)->pREGS; + volatile uint32_t i; + + pREGS->STARTUP = ADC_STARTUP_ENABLE; + for ( i = 0; i < 0x10; i++ ) {} + if ( !(pREGS->STARTUP & ADC_STARTUP_ENABLE) ) { + return ERR_ADC_NO_POWER; + } + + /* If not in by-pass mode do the calibration */ + if ( (pREGS->CALIBR & ADC_CALREQD) && !(pREGS->CTRL & ADC_CR_BYPASS) ) { + uint32_t ctrl = pREGS->CTRL & (CTRL_MASK | 0xFF); + uint32_t tmp = ctrl; + + /* Set ADC to SYNC mode */ + tmp &= ~ADC_CR_ASYNC_MODE; + + /* To be safe run calibration at 1MHz UM permits upto 30MHz */ + if (sysclk_freq > 1000000UL) { + pREGS->CTRL = tmp | (((sysclk_freq / 1000000UL) - 1) & 0xFF); + } + + /* Calibration is needed, do it now. */ + pREGS->CALIBR = ADC_CALIB; + i = 0xF0000; + while ( (pREGS->CALIBR & ADC_CALIB) && --i ) {} + pREGS->CTRL = ctrl; + return i ? LPC_OK : ERR_TIME_OUT; + } + + /* A dummy conversion cycle will be performed. */ + pREGS->STARTUP = (pREGS->STARTUP | ADC_STARTUP_INIT) & 0x03; + i = 0x7FFFF; + while ( (pREGS->STARTUP & ADC_STARTUP_INIT) && --i ) {} + return i ? LPC_OK : ERR_TIME_OUT; +} + +/* EXPORTED API: Configure the ADC */ +ErrorCode_t ADC_Configure(ADC_HANDLE_T hADC, const ADC_CFG_T *pCfg) +{ + ADC_DRIVER_T *pADC = hADC; + ADC_REGS_T *pREGS = pADC->pREGS; + + pADC->valSeq[ADC_SEQ_A] = ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_START | (pCfg->flagSeqA & SEQ_A_MASK); + pADC->valSeq[ADC_SEQ_B] = ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_START | (pCfg->flagSeqB & SEQ_B_MASK); + + /* START is not required for BURST or H/W Trigger */ + if ((pCfg->flagSeqA & ADC_SEQ_CTRL_TRIGGER_MASK)) { + pADC->valSeq[ADC_SEQ_A] &= ~ADC_SEQ_CTRL_START; + } + + /* START is not required for BURST or H/W Trigger */ + if ((pCfg->flagSeqB & ADC_SEQ_CTRL_TRIGGER_MASK)) { + pADC->valSeq[ADC_SEQ_B] &= ~ADC_SEQ_CTRL_START; + } + + pREGS->CTRL = (pCfg->flagCfg & CTRL_MASK) | (pCfg->clkDiv & ADC_CR_CLKDIV_MASK); + + /* Enable/Disable overflow interrupt */ + if (pCfg->flagCfg & ENABLE_OVR) { + pADC->regInt |= ADC_INTEN_OVRRUN_ENABLE; + } + else { + pADC->regInt &= ~ADC_INTEN_OVRRUN_ENABLE; + } + + return LPC_OK; +} + +/* EXPORTED API: Configure channel specific options */ +ErrorCode_t ADC_ConfigureChannel(ADC_HANDLE_T hADC, uint32_t chanNum, uint32_t chanOpts) +{ + ADC_DRIVER_T *pADC = hADC; + + /* Sanity check */ + if (chanNum > ADC_MAX_CHANNEL_NUM) { + return ERR_ADC_PARAM; + } + + pADC->regInt &= ~(0x18 << (chanNum * 2)); + + if (chanOpts & ADC_CH_THRES_SEL1) { + pADC->regThrSel |= 1 << chanNum; + } + else { + pADC->regThrSel &= ~(1 << chanNum); + } + + if (chanOpts & ADC_CH_THRES_CROSSING) { + pADC->regInt |= 0x10 << (chanNum * 2); + } + else if (chanOpts & ADC_CH_THRES_OUTSIDE) { + pADC->regInt |= 0x08 << (chanNum * 2); + } + + if (chanOpts & ADC_CH_DATA_CALLBACK) { + pADC->flags |= CB_DATA(chanNum); + } + else { + pADC->flags &= ~CB_DATA(chanNum); + } + + if (chanOpts & ADC_CH_THRES_CALLBACK) { + pADC->flags |= CB_THRES(chanNum); + } + else { + pADC->flags &= ~CB_THRES(chanNum); + } + + if (chanOpts & ADC_CH_THRES_DATA) { + pADC->flag1 |= 1 << chanNum; + } + else { + pADC->flag1 &= ~(1 << chanNum); + } + + return LPC_OK; +} + +/* EXPORTED API: Start analog to digital conversion on selected sequence */ +ErrorCode_t ADC_StartConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex, void *buff, size_t bufCount) +{ + ADC_DRIVER_T *pADC = hADC; + ADC_BUFFER_T *buf = &pADC->buffer[seqIndex]; + + /* Sanity check on parameters */ + if ((uint32_t) seqIndex > ADC_SEQ_B) { + return ERR_ADC_INVALID_SEQUENCE; + } + + /* If an active conversion is going on set the buffer ptr */ + if (buf->state == ADC_STATE_ACTIVE) { + if (buf->szNext) { + return ERR_BUSY; + } + buf->pNext = buff; + buf->szNext = bufCount; + return LPC_OK; + } + + /* Assign the buffers */ + buf->pCurr = buff; + buf->szCurr = bufCount; + buf->idx = 0; + + /* Invoke the call back before start */ + _ADC_InvokeCallback(pADC, (ADC_CBINDEX_T) (ADC_START_SEQ + (ADC_CBINDEX_T)seqIndex), (void *) &pADC->pREGS); + + buf->state = ADC_STATE_ACTIVE; + pADC->pREGS->SEQ_CTRL[seqIndex] = pADC->valSeq[seqIndex] & ~(ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_START); + pADC->regInt |= (1 << seqIndex); + pADC->pREGS->INTEN = pADC->regInt; + pADC->pREGS->CHAN_THRSEL = pADC->regThrSel; + pADC->pREGS->SEQ_CTRL[seqIndex] = pADC->valSeq[seqIndex]; + + return LPC_OK; +} + +ErrorCode_t ADC_SwTrigger(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex) +{ + ADC_DRIVER_T *pADC = hADC; + + /* Sanity check on parameters */ + if ((uint32_t) seqIndex > ADC_SEQ_B) { + return ERR_ADC_INVALID_SEQUENCE; + } + + pADC->pREGS->SEQ_CTRL[seqIndex] = pADC->valSeq[seqIndex] | ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_START; + return LPC_OK; +} + +/* EXPORTED API: Stop conversion on a given sequence */ +ErrorCode_t ADC_StopConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex) +{ + ADC_DRIVER_T *pADC = hADC; + + /* Sanity check on parameters */ + if ((uint32_t) seqIndex > ADC_SEQ_B) { + return ERR_ADC_INVALID_SEQUENCE; + } + + pADC->regInt &= ~(1 << seqIndex); + pADC->pREGS->INTEN = pADC->regInt; /* Disable interrupts */ + pADC->buffer[seqIndex].state = ADC_STATE_IDLE; /* Set state to IDLE */ + + /* Stop and disable the sequence */ + pADC->pREGS->SEQ_CTRL[seqIndex] = pADC->valSeq[seqIndex] & + ~(ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_BURST | ADC_SEQ_CTRL_START); + _ADC_InvokeCallback(hADC, (ADC_CBINDEX_T)(ADC_STOP_SEQ + (ADC_CBINDEX_T)seqIndex), 0); + return LPC_OK; +} + +/* EXPORTED API: ADC Event handler */ +ErrorCode_t ADC_Handler(ADC_HANDLE_T hADC, ADC_HEVENT_T hEvent) +{ + ADC_DRIVER_T *pADC = hADC; + + switch (hEvent) { + case ADC_EV_SEQ_A_POLL: + return _ADC_Handler_SeqPoll(pADC, ADC_SEQ_A); + + case ADC_EV_SEQ_B_POLL: + return _ADC_Handler_SeqPoll(pADC, ADC_SEQ_B); + + case ADC_EV_SEQ_A_INT: + return _ADC_Handler_Seq(pADC, ADC_SEQ_A); + + case ADC_EV_SEQ_B_INT: + return _ADC_Handler_Seq(pADC, ADC_SEQ_B); + + case ADC_EV_SEQ_A_DMA: + if (!(pADC->valSeq[ADC_SEQ_A] & 0x3F000)) { + ADC_SwTrigger(hADC, ADC_SEQ_A); + } + return LPC_OK; + + case ADC_EV_SEQ_B_DMA: + if (!(pADC->valSeq[ADC_SEQ_B] & 0x3F000)) { + ADC_SwTrigger(hADC, ADC_SEQ_B); + } + return LPC_OK; + + case ADC_EV_OVR_INT: + return _ADC_Handler_Ovr(pADC); + + case ADC_EV_THRES_INT: + return _ADC_Handler_Thres(pADC); + + default: + return ERR_ADC_PARAM; + } +} + +/* EXPROTED API: Returns memory required for ADC driver */ +uint32_t ADC_GetMemSize(void) +{ + return sizeof(ADC_DRIVER_T); +} + +/* EXPORTED API: Function to Get the firmware Version */ +uint32_t ADC_GetDriverVersion(void) +{ + return ADC_DRIVER_VERSION; +} + +/** + * @brief Table of the addresses of all the 12-Bit ADC functions + * @note This table of function pointers is the API interface. + */ +const ROM_ADC_API_T adcrom_api = { + ADC_GetMemSize, + ADC_Init, + ADC_Configure, + ADC_ConfigureChannel, + ADC_SetThreshold, + ADC_RegisterCallback, + ADC_Calibrate, + ADC_Handler, + ADC_StartConversion, + ADC_StopConversion, + ADC_SwTrigger, + ADC_GetDriverVersion, +}; diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..a0337989a3d2833408e230f936ed85ad3ecd88cd --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc.h @@ -0,0 +1,243 @@ +/* + * @brief ADC ROM API declarations and functions + * + * @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 _HW_ADC_H +#define _HW_ADC_H + +/******************* + * INCLUDE FILES * + ********************/ +#include + +#if defined( __CC_ARM ) + #pragma anon_unions +#endif + +/******************* + * EXPORTED MACROS * + ********************/ + +/********************* + * EXPORTED TYPEDEFS * + **********************/ +// ------------------------------------------------------------------------------------------------ +// ----- ADC ----- +// ------------------------------------------------------------------------------------------------ + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x ADC Modification date=3/16/2011 Major revision=0 Minor revision=3 (ADC) + */ + +typedef struct { /*!< (@ 0x40000000) ADC Structure */ + volatile uint32_t CTRL; /*!< (@ 0x40000000) A/D Control Register */ + volatile uint32_t INPUTSEL; /*!< (@ 0x40000004) A/D Input Control Register */ + union { + volatile uint32_t SEQ_CTRL[2]; + struct { + volatile uint32_t SEQA_CTRL; /*!< (@ 0x40000008) A/D SEQA Ctrl Register */ + volatile uint32_t SEQB_CTRL; /*!< (@ 0x4000000C) A/D SEQB Ctrl Register */ + }; + + }; + + union { + const volatile uint32_t SEQ_GDAT[2]; + struct { + const volatile uint32_t SEQA_GDAT; /*!< (@ 0x40000010) A/D SEQA Global Data Register */ + const volatile uint32_t SEQB_GDAT; /*!< (@ 0x40000014) A/D SEQB Global Data Register */ + }; + + }; + + uint32_t Reserved[2]; + union { + const volatile uint32_t DAT[12]; /*!< (@ 0x40000020) A/D Channel Data Register*/ + struct { + const volatile uint32_t DAT0; /*!< (@ 0x40000020) A/D Channel Data Register 0*/ + const volatile uint32_t DAT1; /*!< (@ 0x40000024) A/D Channel Data Register 1*/ + const volatile uint32_t DAT2; /*!< (@ 0x40000028) A/D Channel Data Register 2*/ + const volatile uint32_t DAT3; /*!< (@ 0x4000002C) A/D Channel Data Register 3*/ + const volatile uint32_t DAT4; /*!< (@ 0x40000030) A/D Channel Data Register 4*/ + const volatile uint32_t DAT5; /*!< (@ 0x40000034) A/D Channel Data Register 5*/ + const volatile uint32_t DAT6; /*!< (@ 0x40000038) A/D Channel Data Register 6*/ + const volatile uint32_t DAT7; /*!< (@ 0x4000003C) A/D Channel Data Register 7*/ + const volatile uint32_t DAT8; /*!< (@ 0x40000040) A/D Channel Data Register 8*/ + const volatile uint32_t DAT9; /*!< (@ 0x40000044) A/D Channel Data Register 9*/ + const volatile uint32_t DAT10; /*!< (@ 0x40000048) A/D Channel Data Register 10*/ + const volatile uint32_t DAT11; /*!< (@ 0x4000004C) A/D Channel Data Register 11*/ + }; + + }; + + union { + volatile uint32_t THR_LOW[2]; + struct { + volatile uint32_t THR0_LOW; /*!< (@ 0x40000050) A/D Low Threhold Register 0. */ + volatile uint32_t THR1_LOW; /*!< (@ 0x40000054) A/D Low Threhold Register 1. */ + }; + + }; + + union { + volatile uint32_t THR_HIGH[2]; + struct { + volatile uint32_t THR0_HIGH; /*!< (@ 0x40000058) A/D High Threhold Register 0. */ + volatile uint32_t THR1_HIGH; /*!< (@ 0x4000005C) A/D High Threhold Register 1. */ + }; + + }; + + volatile uint32_t CHAN_THRSEL; /*!< (@ 0x40000060) A/D Channel Threhold Select Register. */ + volatile uint32_t INTEN; /*!< (@ 0x40000064) A/D Interrupt Enable Register. */ + volatile uint32_t FLAGS; /*!< (@ 0x40000068) A/D Interrupt Request Flags Register. */ + volatile uint32_t STARTUP; /*!< (@ 0x4000006C) A/D Startup Register. */ + volatile uint32_t CALIBR; /*!< (@ 0x40000070) A/D Calibration Register. */ +} ADC_REGS_T; + +/** Maximum sample rate in Hz (12-bit conversions) */ +#define ADC_MAX_CHANNEL_NUM 12 + +/** + * @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_ASYNC_MODE (1 << 8) +#define ADC_CR_RESOL_MASK (0x3 << 9) /*!< Two-bit mask for resolution */ +#define ADC_CR_RESOL(n) ((n) << 9) /*!< 2-bits, 6(0x0),8(0x1),10(0x2),12(0x3)-bit mode enable bit */ +#define ADC_CR_RESOL_BITPOS (9) +#define ADC_CR_BYPASS (1 << 11) /*!< Bypass mode */ +#define ADC_CR_TSAMP_MASK (0x7 << 12) /*!< Three-bit mask for Sample time */ + +/** + * @brief ADC resolution bits 9 and 10 + */ +typedef enum _ADC_RESOL_T { + ADC_RESOL_6BIT = 0, + ADC_RESOL_8BIT, + ADC_RESOL_10BIT, + ADC_RESOL_12BIT, +} ADC_RESOL_T; + +/* ADC input Select register */ +#define ADC_INPUTSEL_PIN (0x0 << 0) +#define ADC_INPUTSEL_CORE_VOL (0x1 << 0) +#define ADC_INPUTSEL_INTERNAL_VOL (0x2 << 0) +#define ADC_INPUTSEL_TEMP_VOL (0x3 << 0) + +/** ADC Sequence Control register bit fields */ +#define ADC_SEQ_CTRL_CHANSEL(n) (1 << (n)) /*!< Channel select macro */ +#define ADC_SEQ_CTRL_CHANSEL_BITPOS(n) ((n) << 0) /*!< Channel select macro */ +#define ADC_SEQ_CTRL_CHANSEL_MASK (0xFFF) /*!< Channel select mask */ + +/** SEQ_CTRL register bit fields */ +#define ADC_SEQ_CTRL_TRIGGER(n) ((n) << 12) +#define ADC_SEQ_CTRL_TRIGGER_MASK (0x1F << 12) +#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_DRTHR_RESULT(n) ((((n) >> 4) & 0xFFFF)) /*!< Macro for getting the ADC data value along with Threshold */ +#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 Startup register bit fields */ +#define ADC_STARTUP_ENABLE (0x1 << 0) +#define ADC_STARTUP_INIT (0x1 << 1) + +/* ADC Calibration register definition */ +#define ADC_CALIB (0x1 << 0) +#define ADC_CALREQD (0x1 << 1) + +/* Depending on the mode you are running: the slowest case is using interrupt and end of conversion while BURST mode is enabled. + For interrupt and end of sequence, the clock can be set faster. */ + +#endif /* _HW_ADCD_H Do not add any thing below this line */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..7a48a663eb4a1501a9c41a0e0261e2fd51a3eb57 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_adc_rom_api.h @@ -0,0 +1,216 @@ +/* + * @brief ADC ROM API declarations and functions + * + * @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 __HW_ADC_ROM_API_H +#define __HW_ADC_ROM_API_H + +#include +#include +#include "error.h" +#include "packing.h" +#include "hw_adc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_ADC ADC (12-Bit) ROM driver functions and definitions + * @ingroup ROMAPI_ADC_WRAPPER + * @{ + */ + +/** @brief ADC Handler type */ +typedef void *ADC_HANDLE_T; + +/** @brief ADC SEQ Options */ +#define TRIG_SOFT (0UL << 12) /*!< Software Trigger */ +#define TRIG_PININT0 (0UL << 12) /*!< Hardware Trigger on PININT0 */ +#define TRIG_PININT1 (1UL << 12) /*!< Hardware Trigger on PININT1 */ +#define TRIG_ARMTXEV (5UL << 12) /*!< Hardware Trigger on ARM_TXEV */ +#define TRIG_POL_NEG 0 /*!< Trigger polarity is negative */ +#define TRIG_POL_POS (1UL << 18) /*!< Trigger polarity is positive */ +#define BYPASS_SYNC (1UL << 19) /*!< Bypass Synchronization Filp-Flop */ +#define MODE_BURST (1UL << 27) /*!< Enable Burst mode */ +#define MODE_SINGLE (1UL << 28) /*!< Enable Single mode */ +#define SEQA_PIRO_HIGH (1UL << 29) /*!< Set SEQA as HIGH Priority */ +#define MODE_EOC (0UL << 30) /*!< Event after end of Conversion */ +#define MODE_EOS (1UL << 30) /*!< Event after end of sequence */ +#define ENABLE_CH(ch) (1UL << (ch)) /*!< Enable the channel number */ + +/* Gets the ADC trigger from configuration */ +#define ADC_TRIGGER(cfg) (((cfg) & 0x3F000) >> 12) + +/** @brief ADC DMA source address offsets */ +#define ADC_DMA_SRC_SEQA 4 /*!< DMA Source offset for SEQ_A */ +#define ADC_DMA_SRC_SEQB 5 /*!< DMA Source offset for SEQ_B */ +#define ADC_DMA_SRC_CH0 8 /*!< DMA Source offset for CH0 */ +#define ADC_DMA_SRC_CH1 9 /*!< DMA Source offset for CH1 */ +#define ADC_DMA_SRC_CH2 10 /*!< DMA Source offset for CH2 */ +#define ADC_DMA_SRC_CH3 11 /*!< DMA Source offset for CH3 */ +#define ADC_DMA_SRC_CH4 12 /*!< DMA Source offset for CH4 */ +#define ADC_DMA_SRC_CH5 13 /*!< DMA Source offset for CH5 */ +#define ADC_DMA_SRC_CH6 14 /*!< DMA Source offset for CH6 */ +#define ADC_DMA_SRC_CH7 15 /*!< DMA Source offset for CH7 */ +#define ADC_DMA_SRC_CH8 16 /*!< DMA Source offset for CH8 */ +#define ADC_DMA_SRC_CH9 17 /*!< DMA Source offset for CH9 */ +#define ADC_DMA_SRC_CH10 18 /*!< DMA Source offset for CH10 */ +#define ADC_DMA_SRC_CH11 19 /*!< DMA Source offset for CH11 */ + +/** @brief ADC DMA Source address calculator */ +#define ADC_DMA_ADDR(ptr, src) ((*(uint32_t *) (ptr)) + ((src) << 2)) + +/** @brief ADC CTRL Options */ +#define MODE_SYNC (0UL << 8) /*!< Set ADC to synchoronous mode */ +#define MODE_ASYNC (1UL << 8) /*!< Set ADC to asynchoronous mode */ +#define RESOL_6BIT (0UL << 9) /*!< Set ADC Resolution to 6 bits */ +#define RESOL_8BIT (1UL << 9) /*!< Set ADC Resolution to 8 bits */ +#define RESOL_10BIT (2UL << 9) /*!< Set ADC Resolution to 10 bits */ +#define RESOL_12BIT (3UL << 9) /*!< Set ADC Resolution to 12 bits */ +#define BYPASS_CALIB (1UL << 11) /*!< Bypass calibration data */ +#define SAMPLE_TIME(x) (((x) & 7) << 12) /*!< Set the Sample Time to @a x */ +#define ENABLE_OVR (1UL << 24) /*!< Enable Overflow interrupt */ + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a ADC ROM + * driver handle.
+ * To get a user context, simply use the macro on the driver's handle: + * void *pUserData = ROM_ADC_HANDLE_TOUDATA(hADC); + */ +#define ROM_ADC_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief ADC Threshold select */ +#define SEL_THRES1(ch) (1UL << (ch)) /*!< Select THRESHOLD-1 register */ +#define EN_THRES(ch) (1UL << (16 + (ch))) /*!< Enable Threshold compare */ + +/** @brief Convert DMA data to channel data */ +#define ADC_DATA_CH(data) (((data) >> 4) & 0xFFFF) + +/**@brief Threshold ranges */ +#define ADC_THRES_ABOVE 2 /*!< Threshold is above THRES_HI */ +#define ADC_THRES_BELOW 1 /*!< Threshold is below THRES_LO */ +#define ADC_THRES_INSIDE 0 /*!< Threshold is inside the range */ +#define ADC_THRES_RANGE(data) (((data) >> 12) & 0x3) /*!< Get Threshold range data */ + +/**@brief Threshold crossings */ +#define ADC_THRES_UP 3 /*!< Threshold crossing UP */ +#define ADC_THRES_DOWN 2 /*!< Threshold crossing DOWN */ +#define ADC_THRES_NONE 0 /*!< No threshold crossing */ +#define ADC_THRES_CORSS(data) (((data) >> 14) & 0x3) /*!< Get threshold crossing data */ + +/* @brief ADC Configuration data structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t flagSeqA; /*!< Options for SEQ_A, like triggers, burst/single mode etc; */ + uint32_t flagSeqB; /*!< Options for SEQ_B, like triggers, burst/single mode etc; */ + uint32_t flagCfg; /*!< ADC Configuration flags, like SYNC/ASYNC mode select resolution select etc; see #MODE_SYNC, #RESOL_6BIT, #BYPASS_CALIB and #SAMPLE_TIME */ + uint32_t clkDiv; /*!< Clock divider value to be used in SYNC mode; not valid #MODE_ASYNC is present in #flagCfg */ +} ADC_CFG_T; + +/** @brief Event handler, event types */ +typedef enum { + ADC_EV_SEQ_A_POLL, /*!< SEQ_A Polling */ + ADC_EV_SEQ_B_POLL, /*!< SEQ_B Polling */ + ADC_EV_SEQ_A_INT, /*!< SEQ_A Interrupt */ + ADC_EV_SEQ_B_INT, /*!< SEQ_B Interrupt */ + ADC_EV_SEQ_A_DMA, /*!< SEQ_A DMA Event */ + ADC_EV_SEQ_B_DMA, /*!< SEQ_B DMA Event */ + ADC_EV_OVR_INT, /*!< Overflow interrupt */ + ADC_EV_THRES_INT, /*!< Threshold interrupt */ +} ADC_HEVENT_T; + +/** @brief Channel configuration options */ +#define ADC_CH_THRES_SEL1 0x01 /*!< Use THRES1 for threshold compare */ +#define ADC_CH_THRES_CALLBACK 0x02 /*!< Enable threshold callback event */ +#define ADC_CH_THRES_OUTSIDE 0x04 /*!< Enable threshold outside event */ +#define ADC_CH_THRES_CROSSING 0x08 /*!< Enable threshold crossing event */ +#define ADC_CH_DATA_CALLBACK 0x10 /*!< Enable callback for data available */ +#define ADC_CH_THRES_DATA 0x20 /*!< Add threshold value to DATA */ + +/** @brief Macros to extract information from call-back flags */ +#define ADC_OVR_SEQ_A(flag) (((flag) >> 12) & 1) /*!< Overflow in SEQ_A */ +#define ADC_OVR_SEQ_B(flag) (((flag) >> 13) & 1) /*!< Overflow in SEQ_B */ + +/** @brief Index to call-back functions */ +typedef enum { + ADC_START_SEQ, /*!< Start SEQ event */ + ADC_START_SEQ_A = ADC_START_SEQ, /*!< Start SEQ_A event */ + ADC_START_SEQ_B, /*!< Start SEQ_B event */ + ADC_STOP_SEQ, /*!< Stop SEQ event */ + ADC_STOP_SEQ_A = ADC_STOP_SEQ, /*!< Stop SEQ_A event */ + ADC_STOP_SEQ_B, /*!< Stop SEQ_B event */ + ADC_BUFFER_DONE, /*!< ADC Buffer full event */ + ADC_BUFFER_DONE_A = ADC_BUFFER_DONE, /*!< ADC Buffer full event for SEQ_A */ + ADC_BUFFER_DONE_B, /*!< ADC Buffer full event for SEQ_B */ + ADC_CHDATA, /*!< Data for Channel available */ + ADC_OVERFLOW, /*!< Over flow event */ + ADC_THRESHOLD, /*!< Threshold event */ + ADC_CBIDX_RESERVED, /*!< Reserved value (should not be used) */ +} ADC_CBINDEX_T; + +/** @brief ADC Sequence index */ +typedef enum { + ADC_SEQ_A, /*!< Index for Sequence A */ + ADC_SEQ_B, /*!< Index for Sequence B */ +} ADC_SEQ_INDEX_T; + +/** + * @brief Structure that has the API pointers in ROM Table + */ +typedef PRE_PACK struct POST_PACK { + /* Index of All the 12-Bit ADC driver APIs */ + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of ADC driver */ + ADC_HANDLE_T (*Init)(void *pMem, uint32_t baseAddr, void *pUserData); /*!< Initializes the ADC driver and peripheral */ + ErrorCode_t (*Configure)(ADC_HANDLE_T hADC, const ADC_CFG_T *pCfg); /*!< Configure the ADC to given parameters like resolution etc. */ + ErrorCode_t (*ConfigureCh)(ADC_HANDLE_T hADC, uint32_t chanNum, uint32_t chanOpts); /*!< Configure channel specific options */ + void (*SetThreshold)(ADC_HANDLE_T hADC, uint32_t valThr0, uint32_t valThr1);/*!< Set the threshold values for THRES0 (HIGH & LOW) and THRES1 (HIGH & LOW) */ + ErrorCode_t (*RegisterCB)(ADC_HANDLE_T hADC, ADC_CBINDEX_T cbIndex, + void (*pCbFunc)(ADC_HANDLE_T, ADC_CBINDEX_T, void *)); /*!< Registers an ADC callback function */ + ErrorCode_t (*Calibrate)(ADC_HANDLE_T hADC, uint32_t sysclk_freq); /*!< Calibrate the ADC peripheral */ + ErrorCode_t (*Handler)(ADC_HANDLE_T hADC, ADC_HEVENT_T event); /*!< ADC Event handler, should be called from the ISR */ + ErrorCode_t (*StartConversion)(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex, void *buffer, size_t bufCount); /*!< Start sampling of ADC inputs */ + ErrorCode_t (*StopConversion)(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex); /*!< Stop sampling of ADC inputs */ + ErrorCode_t (*SwTrigger)(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex); /*!< Generate a software trigger */ + uint32_t (*GetDriverVersion)(void); /*!< Get the version of the Driver Firmware in ROM */ +} ROM_ADC_API_T; + +/* Extern declaration so that application can access + * pointer to the function table + */ +extern const ROM_ADC_API_T adcrom_api; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __HW_ADCD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.c new file mode 100644 index 0000000000000000000000000000000000000000..08ea3c5b37250f7f2fda884d64264c50bf608c04 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.c @@ -0,0 +1,624 @@ +/* + * @brief DMA controller ROM API declarations and functions + * + * @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 +#include +#include "hw_dmaaltd.h" + +#define DRVVERSION 0x0100 + +typedef PRE_PACK struct POST_PACK { + uint32_t xfercfg; /*!< DMA Configuration register */ + uint32_t src; /*!< DMA source address */ + uint32_t dest; /*!< DMA destination address */ + ROM_DMA_DESC_T *pNextLink; /*!< Pointer to next descriptor link in a chain, NULL to end */ +} ROM_DMA_PRVXFERDESC_T; + +/* Private data structure used for the DMA controller driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_DMA_T *base; /*!< Base address of DMA controller to use */ + ROM_DMA_PRVXFERDESC_T *sramBase; /*!< SRAM descriptor table (all channels) */ + ROM_DMA_QUEUE_T *pQueueHead; /*!< Pointer to linked list of queue descriptors */ +} DMA_DATACONTEXT_T; + +static const uint8_t mskAlign[3] = {0x0, 0x1, 0x3}; +static const uint8_t widthBytes[3] = {0x1, 0x2, 0x4}; + +#define _dma_ch_int_enable(p, ch) ((p)->DMACOMMON[0].INTENSET = (1 << (ch))) /* Enable interrupts for a channel */ +#define _dma_ch_int_disable(p, ch) ((p)->DMACOMMON[0].INTENCLR = (1 << (ch))) /* Disable interrupts for a channel */ +#define _dma_ch_enable(p, ch) ((p)->DMACOMMON[0].ENABLESET = (1 << (ch))) /* Enable a channel */ +#define _dma_ch_disable(p, ch) ((p)->DMACOMMON[0].ENABLECLR = (1 << (ch))) /* Disable a channel */ + +static void _dma_abort_ch(LPC_DMA_T *pDMA, uint8_t dmaCh) +{ + _dma_ch_disable(pDMA, dmaCh); + + /* Wait for channel to go unbusy */ + while ((pDMA->DMACOMMON[0].BUSY & (1 << dmaCh)) != 0) {} + + /* Abort */ + pDMA->DMACOMMON[0].ABORT = (1 << dmaCh); +} + +static void _dma_start_desc_chain(DMA_DATACONTEXT_T *pDrv, uint8_t dmaCh, ROM_DMA_DESC_T *pDesc) +{ + /* Switch to busy state */ + pDesc->status = ROM_DMA_DESC_STS_BUSY; + + /* Move transfer descriptor to DMA table */ + pDrv->sramBase[dmaCh].xfercfg = pDesc->xfercfg; + pDrv->sramBase[dmaCh].src = pDesc->src; + pDrv->sramBase[dmaCh].dest = pDesc->dest; + pDrv->sramBase[dmaCh].pNextLink = (ROM_DMA_DESC_T *) pDesc->pNextLink; + + /* Start transfer */ + pDrv->base->DMACH[dmaCh].XFERCFG = pDesc->xfercfg; +} + +// ********************************************************** +uint32_t dmaalt_get_mem_size(void) +{ + return sizeof(DMA_DATACONTEXT_T); +} + +ROM_DMA_HANDLE_T dmaalt_init(void *mem, const ROM_DMA_INIT_T *pInit) +{ + DMA_DATACONTEXT_T *pDrv; + + /* Verify alignment is at least 4 bytes */ + if (((uint32_t) mem & 0x3) != 0) { + return NULL; + } + + pDrv = (DMA_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(DMA_DATACONTEXT_T)); + + /* Save pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_DMA_T *) pInit->base; + pDrv->sramBase = (ROM_DMA_PRVXFERDESC_T *) pInit->sramBase; + + /* Enable DMA controller */ + pDrv->base->CTRL = 1; + pDrv->base->SRAMBASE = (uint32_t) pInit->sramBase; + + return (ROM_DMA_HANDLE_T) pDrv; +} + +ErrorCode_t dmaalt_setup_channel(ROM_DMA_HANDLE_T pHandle, ROM_DMA_CHAN_CFG_T *pCfg, uint8_t dmaCh) +{ + uint32_t cfg; + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + /* Parameter checks */ + if ((pCfg->burstSize > (uint32_t) ROM_DMA_BURSTPOWER_1024) || (pCfg->channelPrio > 7)) { + return ERR_DMA_PARAM; + } + + /* Enable DMA channel, clear any errors, enable interrupts */ + pDrv->base->DMACOMMON[0].ENABLECLR = (1 << dmaCh); + pDrv->base->DMACOMMON[0].ERRINT = (1 << dmaCh); + pDrv->base->DMACOMMON[0].INTA = (1 << dmaCh); + pDrv->base->DMACOMMON[0].INTB = (1 << dmaCh); + + /* Basic DMA configuration */ + if (pCfg->periphReq) { + cfg = DMA_CFG_PERIPHREQEN; + } + else { + /* Hardware triggering */ + cfg = DMA_CFG_HWTRIGEN; + cfg |= (pCfg->triggerPolHi << 4) | (pCfg->triggerLevel << 5) | (pCfg->triggerBurst << 6); + } + cfg |= (pCfg->burstSize << 8) | (pCfg->srcBurstWrap << 14) | (pCfg->dstBurstWrap << 15) | (pCfg->channelPrio << 16); + pDrv->base->DMACH[dmaCh].CFG = cfg; + + return LPC_OK; +} + +ErrorCode_t dmaalt_init_queue(ROM_DMA_HANDLE_T pHandle, uint8_t dmaCh, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + /* Check queue structure alignment */ + if (((uint32_t) pQueue & 0x3) != 0) { + /* Not aligned at 4 bytes, error */ + return ERR_DMA_NOT_ALIGNMENT; + } + + memset(pQueue, 0, sizeof(ROM_DMA_QUEUE_T)); + + /* Save DMA channekl for this queue */ + pQueue->dmaCh = dmaCh; + + /* Append to existing queue */ + if (pDrv->pQueueHead) { + pQueue->pQueueHead = (struct ROM_DMA_QUEUE *) pDrv->pQueueHead; + } + pDrv->pQueueHead = pQueue; + pQueue->queueSt = (uint8_t) ROM_QUEUE_ST_IDLE; + + return LPC_OK; +} + +void dmaalt_register_queue_callback(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, uint32_t cbIndex, void *pCB) +{ + switch (cbIndex) { + case ROM_DMA_XFERCOMPLETE_CB: + pQueue->dmaCompCB = (dmaTransferCompleteCB) pCB; + break; + + case ROM_DMA_XFERDESCCOMPLETE_CB: + pQueue->dmaDescCompCB = (dmaTransferDescCompleteCB) pCB; + break; + + case ROM_DMA_XFERERROR_CB: + pQueue->dmaErrorCB = (dmaTransferErrorCB) pCB; + break; + } +} + +ErrorCode_t dmaalt_build_descriptor_chain(ROM_DMA_HANDLE_T pHandle, + ROM_DMA_XFERDESC_CFG_T *pXferCfg, + ROM_DMA_DESC_T *pDesc, + ROM_DMA_DESC_T *pDescPrev) +{ + uint32_t cfg, xfercnt, burstSize; + uint8_t srcWrap, destWrap; + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + /* Parameter checks */ + if (pDesc == NULL) { + return ERR_DMA_PARAM; + } + + /* Passed descriptor must be correctly aligned */ + if (((uint32_t) pDesc & 0xF) != 0) { + return ERR_DMA_NOT_ALIGNMENT; + } + + /* Parameter checks */ + if (pXferCfg->width > (uint8_t) ROM_DMA_WIDTH_4) { + return ERR_DMA_PARAM; + } + if ((pXferCfg->srcInc > (uint8_t) ROM_DMA_ADDRINC_4X) || + (pXferCfg->dstInc > (uint8_t) ROM_DMA_ADDRINC_4X)) { + return ERR_DMA_PARAM; + } + if ((pXferCfg->xferCount < 1) || (pXferCfg->xferCount > 1024)) { + return ERR_DMA_PARAM; + } + xfercnt = pXferCfg->xferCount - 1; /* Adjust for use with DMA */ + + /* Check source and destination address alignment */ + if (((uint32_t) pXferCfg->src & mskAlign[pXferCfg->width]) != 0) { + return ERR_DMA_NOT_ALIGNMENT; + } + if (((uint32_t) pXferCfg->dest & mskAlign[pXferCfg->width]) != 0) { + return ERR_DMA_NOT_ALIGNMENT; + } + + /* Get source and destination wrap states for the channel */ + cfg = pDrv->base->DMACH[pXferCfg->dmaCh].CFG; + + /* Get burst size in datum count, used for wrap end address, offset by + (-1) for end address computation */ + burstSize = (1 << ((cfg >> 8) & 0xF)) - 1; + + /* Setup source transfer address */ + if (pXferCfg->srcInc == ROM_DMA_ADDRINC_0X) { + /* No address increment - even with burst - so source address doesn't need + to be adjusted */ + pDesc->src = (uint32_t) pXferCfg->src; + } + else { + srcWrap = (uint8_t) ((cfg & (1 << 14)) != 0); + if (srcWrap) { + /* Wrap enabled - compute end address based on burst size and datum width */ + pDesc->src = (uint32_t) pXferCfg->src + ((uint32_t) widthBytes[pXferCfg->width] * + burstSize * (1 << ((uint32_t) pXferCfg->srcInc - 1))); + } + else { + /* No wrap - compute end address based on transfer size and datum width */ + pDesc->src = (uint32_t) pXferCfg->src + ((uint32_t) widthBytes[pXferCfg->width] * + xfercnt * (1 << ((uint32_t) pXferCfg->srcInc - 1))); + } + } + + /* Setup destination transfer address */ + if (pXferCfg->dstInc == ROM_DMA_ADDRINC_0X) { + /* No address increment - even with burst - so destination address doesn't need + to be adjusted */ + pDesc->dest = (uint32_t) pXferCfg->dest; + } + else { + destWrap = (uint8_t) ((cfg & (1 << 15)) != 0); + if (destWrap) { + /* Wrap enabled - compute end address based on burst size and datum width */ + pDesc->dest = (uint32_t) pXferCfg->dest + ((uint32_t) widthBytes[pXferCfg->width] * + burstSize * (1 << ((uint32_t) pXferCfg->dstInc - 1))); + } + else { + /* No wrap - compute end address based on transfer size and datum width */ + pDesc->dest = (uint32_t) pXferCfg->dest + ((uint32_t) widthBytes[pXferCfg->width] * + xfercnt * (1 << ((uint32_t) pXferCfg->dstInc - 1))); + } + } + + /* Save pointer to user data context */ + pDesc->pUserData = pXferCfg->pUserData; + + /* Is the descriptor linked from a previous descriptor? */ + if (pDescPrev) { + pDescPrev->pNextLink = (struct ROM_DMA_DESC *) pDesc; + + if (pXferCfg->enabCirc == 0) { + pDescPrev->xfercfg &= ~(1 << 5);/* Disables INTB on previous descriptor link */ + pDescPrev->xfercfg |= (1 << 1); /* Reload on chained links */ + } + } + else { + pDesc->pNextLink = NULL; + } + + /* NULL out next chain descriptor pointers. The next chain descriptor is + managed by the queue function, while the next link descriptor indicates the end + of a chain. */ + pDesc->pNextChain = NULL; + + /* Current descriptor status is queueing. Status only applies to the first descriptor + in a chain. */ + pDesc->status = ROM_DMA_DESC_STS_QUEUEING; + pDesc->savedXferSize = pXferCfg->xferCount; + + /* Normalize parameters that are multibit to single bit */ + pXferCfg->swTrig = (pXferCfg->swTrig != 0); + pXferCfg->clrTrig = (pXferCfg->clrTrig != 0); + pXferCfg->fireDescCB = (pXferCfg->fireDescCB != 0); + + if (pXferCfg->enabCirc) { + cfg = (1 << 1); /* Reload on chained links */ + } + else { + cfg = (1 << 5); /* INTB support for completion and next descriptor */ + } + if (pXferCfg->stallDesc == 0) { + cfg |= 0x1; /* CFGVALID */ + } + + /* Setup transfer configuration */ + cfg |= (pXferCfg->swTrig << 2) | (pXferCfg->clrTrig << 3) | + (pXferCfg->fireDescCB << 4) | (pXferCfg->width << 8) | (pXferCfg->srcInc << 12) | + (pXferCfg->dstInc << 14); + cfg |= (xfercnt << 16); + pDesc->xfercfg = cfg; + + return LPC_OK; +} + +uint32_t dmaalt_get_transfer_count(ROM_DMA_HANDLE_T pHandle, ROM_DMA_DESC_T *pDesc) +{ + uint32_t dataCount = 0; + + /* Count is only valid if descriptor is used */ + while (pDesc != NULL) { + if (pDesc->status == ROM_DMA_DESC_STS_SPENT) { + dataCount += (uint32_t) pDesc->savedXferSize; + } + + pDesc = (ROM_DMA_DESC_T *) pDesc->pNextLink; + } + + return dataCount; +} + +void dmaalt_unstall_descriptor_chain(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + pDrv->base->DMACOMMON[0].SETVALID = (1 << pQueue->dmaCh); +} + +void dmaalt_queue_descriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, ROM_DMA_DESC_T *pDescChainHead) +{ + /* Add the link to the passed descriptor to the end of the queue */ + if (pQueue->pDescEnd != NULL) { + pQueue->pDescEnd->pNextChain = (struct ROM_DMA_DESC *) pDescChainHead; + } + pQueue->pDescEnd = pDescChainHead; + + /* Next descriptor in queue */ + if (pQueue->pDescNext == NULL) { + pQueue->pDescNext = pDescChainHead; + } + + /* Descriptor is ready */ + pDescChainHead->status = ROM_DMA_DESC_STS_READY; +} + +ROM_DMA_DESC_STS_T dmaalt_get_queue_pop_descriptor_status(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + if (pQueue->pDescPop) { + return (ROM_DMA_DESC_STS_T) pQueue->pDescPop->status; + } + + return ROM_DMA_DESC_STS_INVALID; +} + +ROM_DMA_DESC_T *dmaalt_unqueue_descriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + ROM_DMA_DESC_T *pDesc = NULL; + + /* Get current queue pop descriptor */ + if (pQueue->pDescPop) { + /* Only expired (spent, error, or aborted descriptors can be unqueued. Use StopQueue to halt all + descriptors queued. */ + if (pQueue->pDescPop->status >= ROM_DMA_DESC_STS_SPENT) { + pDesc = (ROM_DMA_DESC_T *) pQueue->pDescPop; + pQueue->pDescPop = (ROM_DMA_DESC_T *) pQueue->pDescPop->pNextChain; + } + } + + return pDesc; +} + +ErrorCode_t dmaalt_start_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + /* Is DMA already running? No need to restart */ + if ((pDrv->base->DMACOMMON[0].ACTIVE & (1 << pQueue->dmaCh)) != 0) { + return LPC_OK; + } + + /* Is queue empty? */ + if (pQueue->pDescNext == NULL) { + return ERR_DMA_QUEUE_EMPTY; + } + + /* Does the queue currently have a descriptor in it? */ + if (pQueue->pDescNext) { + /* Is current descriptor chain ready? */ + if (pQueue->pDescNext->status == ROM_DMA_DESC_STS_READY) { + /* Queue is now running */ + pQueue->queueSt = (uint8_t) ROM_QUEUE_ST_RUNNING; + + /* Enable this channel */ + _dma_ch_enable(pDrv->base, pQueue->dmaCh); + _dma_ch_int_enable(pDrv->base, pQueue->dmaCh); + + _dma_start_desc_chain(pDrv, pQueue->dmaCh, pQueue->pDescNext); + } + } + + return LPC_OK; +} + +ErrorCode_t dmaalt_stop_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + ErrorCode_t error = LPC_OK; + + /* Disable interrupts for this channel */ + _dma_ch_int_disable(pDrv->base, pQueue->dmaCh); + + /* If queue is empty, no need to stop */ + if (pQueue->pDescNext == NULL) { + return LPC_OK; + } + + /* If current transfer is queued or ready, then switch it to aborted status + and call completion callback if needed. */ + if (pQueue->pDescNext->status == ROM_DMA_DESC_STS_BUSY) { + /* Abort transfer */ + _dma_abort_ch(pDrv->base, pQueue->dmaCh); + } + else if (!((pQueue->pDescNext->status == ROM_DMA_DESC_STS_QUEUEING) || + (pQueue->pDescNext->status == ROM_DMA_DESC_STS_READY))) { + /* Other statuses are not legal for a queued descriptor */ + error = ERR_DMA_GENERAL; + } + + /* Unlatch interrupts */ + pDrv->base->DMACOMMON[0].ERRINT = (1 << pQueue->dmaCh); + pDrv->base->DMACOMMON[0].INTA = (1 << pQueue->dmaCh); + pDrv->base->DMACOMMON[0].INTB = (1 << pQueue->dmaCh); + + /* Call completion callback to indicate abort state */ + pQueue->pDescNext->status = ROM_DMA_DESC_STS_ABORT; + if (pQueue->dmaCompCB) { + pQueue->dmaCompCB(pHandle, (struct ROM_DMA_QUEUE *) pQueue, pQueue->pDescNext); + } + + /* Increment to next available descriptor since this one was aborted */ + pQueue->pDescNext = (ROM_DMA_DESC_T *) pQueue->pDescNext->pNextChain; + + /* Queue is now idle */ + pQueue->queueSt = (uint8_t) ROM_QUEUE_ST_IDLE; + + return error; +} + +void dmaalt_flush_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + /* Disable interrupts for this channel */ + _dma_ch_int_disable(pDrv->base, pQueue->dmaCh); + + /* Abort transfer */ + _dma_abort_ch(pDrv->base, pQueue->dmaCh); + + /* Unlatch interrupts */ + pDrv->base->DMACOMMON[0].ERRINT = (1 << pQueue->dmaCh); + pDrv->base->DMACOMMON[0].INTA = (1 << pQueue->dmaCh); + pDrv->base->DMACOMMON[0].INTB = (1 << pQueue->dmaCh); + + /* No callbacks on abort, all descriptors flushed */ + pQueue->pDescEnd = pQueue->pDescNext = pQueue->pDescPop = NULL; + + /* Queue is now idle */ + pQueue->queueSt = (uint8_t) ROM_QUEUE_ST_IDLE; +} + +uint8_t dmaalt_get_queue_state(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + return pQueue->queueSt; +} + +void dmaalt_force_trigger(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + + pDrv->base->DMACOMMON[0].SETTRIG = (1 << pQueue->dmaCh); +} + +// Otime = "optimize for speed of code execution" +// ...add this pragma 1 line above the interrupt service routine function. +void dmaalt_handler(ROM_DMA_HANDLE_T pHandle) +{ + uint32_t err, inta, intb, all, dmaChMask; + ROM_DMA_QUEUE_T *pQueue; + ROM_DMA_DESC_T *pDesc; + DMA_DATACONTEXT_T *pDrv = (DMA_DATACONTEXT_T *) pHandle; + uint8_t nextChain = 0; + + /* DMA interrupt fires on one of three possible events: + 1) ERROR : A DMA error has occured + Calls error callback and stops queue + 2) INTA on descriptor completion + Calls descriptor completed callback + 3) INTB on descriptor chain completion + Calls descriptor chain completion callback */ + + /* Loop through all enabled DMA channels */ + pQueue = pDrv->pQueueHead; + err = pDrv->base->DMACOMMON[0].ERRINT; + inta = pDrv->base->DMACOMMON[0].INTA; + intb = pDrv->base->DMACOMMON[0].INTB; + all = err | inta | intb; + while (pQueue) { + dmaChMask = (1 << pQueue->dmaCh); + if ((all & dmaChMask) != 0) { + /* DMA interrupt fire for this channel */ + if ((err & dmaChMask) != 0) { + /* Abort current descriptor */ + _dma_ch_int_disable(pDrv->base, pQueue->dmaCh); + _dma_abort_ch(pDrv->base, pQueue->dmaCh); + + /* Error interrupt, clear */ + pDrv->base->DMACOMMON[0].ERRINT = dmaChMask; + pDrv->base->DMACOMMON[0].INTA = dmaChMask; + pDrv->base->DMACOMMON[0].INTB = dmaChMask; + + /* Update status to error */ + pQueue->pDescNext->status = ROM_DMA_DESC_STS_ERROR; + pQueue->queueSt = (uint8_t) ROM_QUEUE_ST_ERROR; + + /* Call error callback for channel */ + if (pQueue->dmaErrorCB) { + pQueue->dmaErrorCB(pHandle, (struct ROM_DMA_QUEUE *) pQueue, pQueue->pDescNext); + } + + nextChain = 1; + } + + /* Interrupt A is used for user defined interrupt tied to a descriptor */ + if ((inta & dmaChMask) != 0) { + pDrv->base->DMACOMMON[0].INTA = dmaChMask; + + /* Call transfer descriptor completion for channel */ + if (pQueue->dmaDescCompCB) { + pQueue->dmaDescCompCB(pHandle, (struct ROM_DMA_QUEUE *) pQueue, pQueue->pDescNext); + } + } + + /* Interrupt B is used for user transfer descriptor chain completion */ + if ((intb & dmaChMask) != 0) { + pDrv->base->DMACOMMON[0].INTB = dmaChMask; + + /* Update status to spent/complete */ + pQueue->pDescNext->status = ROM_DMA_DESC_STS_SPENT; + + /* Start the next descriptor chain? */ + pDesc = (ROM_DMA_DESC_T *) pQueue->pDescNext->pNextChain; + if ((pDesc) && (pDesc->status == ROM_DMA_DESC_STS_READY)) { + /* A queued descriptor is available and ready, so start it */ + _dma_start_desc_chain(pDrv, pQueue->dmaCh, pDesc); + } + + /* Call transfer descriptor completion for channel */ + if (pQueue->dmaCompCB) { + pQueue->dmaCompCB(pHandle, (struct ROM_DMA_QUEUE *) pQueue, pQueue->pDescNext); + } + + nextChain = 1; + } + + if (nextChain) { + /* Need to save in pop queue? */ + if (pQueue->pDescPop == NULL) { + pQueue->pDescPop = pQueue->pDescNext; + } + + /* Advance to next queued descriptor */ + pQueue->pDescNext = (ROM_DMA_DESC_T *) pQueue->pDescNext->pNextChain; + if (pQueue->pDescNext == NULL) { + /* No more descriptors */ + pQueue->pDescEnd = NULL; + } + } + + all &= ~dmaChMask; + } + + /* Next queue */ + pQueue = (ROM_DMA_QUEUE_T *) pQueue->pQueueHead; + } + + if (all) { + /* Unexpected interrupts, clear and disable */ + pDrv->base->DMACOMMON[0].ENABLECLR = all; + pDrv->base->DMACOMMON[0].INTENCLR = all; + pDrv->base->DMACOMMON[0].ERRINT = all; + pDrv->base->DMACOMMON[0].INTA = all; + pDrv->base->DMACOMMON[0].INTB = all; + } +} + +uint32_t dmaalt_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.h new file mode 100644 index 0000000000000000000000000000000000000000..8436254fbeb0af87906363b1ea18cba7919d2099 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd.h @@ -0,0 +1,80 @@ +/* + * @brief DMA master ROM API declarations and functions + * + * @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 __HW_DMAALTD_H +#define __HW_DMAALTD_H + +#include "error.h" +#include "hw_dmaaltd_rom_api.h" + +// *** DMA controller functions called by Application Program *** +uint32_t dmaalt_get_mem_size(void); + +ROM_DMA_HANDLE_T dmaalt_init(void *mem, const ROM_DMA_INIT_T *pInit); + +ErrorCode_t dmaalt_setup_channel(ROM_DMA_HANDLE_T pHandle, ROM_DMA_CHAN_CFG_T *pCfg, uint8_t dmaCh); + +ErrorCode_t dmaalt_init_queue(ROM_DMA_HANDLE_T pHandle, uint8_t dmaCh, ROM_DMA_QUEUE_T *pQueue); + +void dmaalt_register_queue_callback(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, uint32_t cbIndex, void *pCB); + +ErrorCode_t dmaalt_build_descriptor_chain(ROM_DMA_HANDLE_T pHandle, + ROM_DMA_XFERDESC_CFG_T *pXferCfg, + ROM_DMA_DESC_T *pDesc, + ROM_DMA_DESC_T *pDescPrev); + +uint32_t dmaalt_get_transfer_count(ROM_DMA_HANDLE_T pHandle, ROM_DMA_DESC_T *pDesc); + +void dmaalt_unstall_descriptor_chain(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +void dmaalt_queue_descriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, ROM_DMA_DESC_T *pDescChainHead); + +ROM_DMA_DESC_STS_T dmaalt_get_queue_pop_descriptor_status(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +ROM_DMA_DESC_T *dmaalt_unqueue_descriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +ErrorCode_t dmaalt_start_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +ErrorCode_t dmaalt_stop_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +void dmaalt_flush_queue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +uint8_t dmaalt_get_queue_state(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +void dmaalt_force_trigger(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +void dmaalt_handler(ROM_DMA_HANDLE_T pHandle); + +uint32_t dmaalt_get_driver_version(void); + +// *** + +#endif /* __HW_DMAALTD_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_regs.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_regs.h new file mode 100644 index 0000000000000000000000000000000000000000..a21602c597bfa3bbab0f206039c7fd98d0c87896 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_regs.h @@ -0,0 +1,147 @@ +/* + * @brief DMA master ROM API declarations and functions + * + * @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 __HW_DMA_REGS_H_ +#define __HW_DMA_REGS_H_ + +/** + * @brief DMA Controller shared registers structure + */ +typedef struct { /*!< DMA shared registers structure */ + volatile uint32_t ENABLESET; /*!< DMA Channel Enable read and Set for all DMA channels */ + volatile uint32_t RESERVED0; + volatile uint32_t ENABLECLR; /*!< DMA Channel Enable Clear for all DMA channels */ + volatile uint32_t RESERVED1; + volatile uint32_t ACTIVE; /*!< DMA Channel Active status for all DMA channels */ + volatile uint32_t RESERVED2; + volatile uint32_t BUSY; /*!< DMA Channel Busy status for all DMA channels */ + volatile uint32_t RESERVED3; + volatile uint32_t ERRINT; /*!< DMA Error Interrupt status for all DMA channels */ + volatile uint32_t RESERVED4; + volatile uint32_t INTENSET; /*!< DMA Interrupt Enable read and Set for all DMA channels */ + volatile uint32_t RESERVED5; + volatile uint32_t INTENCLR; /*!< DMA Interrupt Enable Clear for all DMA channels */ + volatile uint32_t RESERVED6; + volatile uint32_t INTA; /*!< DMA Interrupt A status for all DMA channels */ + volatile uint32_t RESERVED7; + volatile uint32_t INTB; /*!< DMA Interrupt B status for all DMA channels */ + volatile uint32_t RESERVED8; + volatile uint32_t SETVALID; /*!< DMA Set ValidPending control bits for all DMA channels */ + volatile uint32_t RESERVED9; + volatile uint32_t SETTRIG; /*!< DMA Set Trigger control bits for all DMA channels */ + volatile uint32_t RESERVED10; + volatile 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 */ + volatile uint32_t CFG; /*!< DMA Configuration register */ + volatile uint32_t CTLSTAT; /*!< DMA Control and status register */ + volatile uint32_t XFERCFG; /*!< DMA Transfer configuration register */ + volatile uint32_t RESERVED; +} LPC_DMA_CHANNEL_T; + +/* On LPC540XX, Max DMA channel is 22 */ +#define MAX_DMA_CHANNEL (22) + +/** + * @brief DMA Controller register block structure + */ +typedef struct { /*!< DMA Structure */ + volatile uint32_t CTRL; /*!< DMA control register */ + volatile uint32_t INTSTAT; /*!< DMA Interrupt status register */ + volatile uint32_t SRAMBASE; /*!< DMA SRAM address of the channel configuration table */ + volatile uint32_t RESERVED2[5]; + LPC_DMA_COMMON_T DMACOMMON[1]; /*!< DMA shared channel (common) registers */ + volatile uint32_t RESERVED0[225]; + LPC_DMA_CHANNEL_T DMACH[MAX_DMA_CHANNEL]; /*!< DMA channel registers */ +} LPC_DMA_T; + +/* 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 */ + +/* 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) */ + +/* 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 */ + +/* 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 */ + +#endif /* __HW_DMA_REGS_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..03371ff6bad627365cc805c72499f90783b51384 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.c @@ -0,0 +1,53 @@ +/* + * @brief DMA controller ROM API declarations and functions + * + * @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 "hw_dmaaltd.h" + +const ROM_DMAALTD_API_T dmaalt_api = { + &dmaalt_get_mem_size, + &dmaalt_init, + &dmaalt_setup_channel, + &dmaalt_init_queue, + &dmaalt_register_queue_callback, + &dmaalt_build_descriptor_chain, + &dmaalt_get_transfer_count, + &dmaalt_unstall_descriptor_chain, + &dmaalt_queue_descriptor, + &dmaalt_get_queue_pop_descriptor_status, + &dmaalt_unqueue_descriptor, + &dmaalt_start_queue, + &dmaalt_stop_queue, + &dmaalt_flush_queue, + &dmaalt_get_queue_state, + &dmaalt_force_trigger, + &dmaalt_handler, + &dmaalt_get_driver_version +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..5369eb503d1111a57395a05f20c4eeb95f6f9781 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_dmaaltd_rom_api.h @@ -0,0 +1,306 @@ +/* + * @brief DMA master ROM API declarations and functions + * + * @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 __HW_DMAALTD_ROM_API_H +#define __HW_DMAALTD_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_dmaaltd_regs.h" + +/** @defgroup ROMAPI_DMAALT DMA controller ROM driver functions and definitions + * @ingroup ROMAPI_DMA_WRAPPER + * @{ + */ + +/** @brief DMA controller handle type */ +typedef void *ROM_DMA_HANDLE_T; + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a DMA controller + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_DMA_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_DMA_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief DMA channel mapping + * Each channel is mapped to an individual peripheral and direction or a DMA + * imput mux trigger. + */ +typedef enum { + ROM_DMAREQ_UART0_RX = 0, /*!< UART00 receive DMA channel */ + ROM_DMA_CH0 = ROM_DMAREQ_UART0_RX, + ROM_DMAREQ_UART0_TX, /*!< UART0 transmit DMA channel */ + ROM_DMA_CH1 = ROM_DMAREQ_UART0_TX, + ROM_DMAREQ_UART1_RX, /*!< UART1 receive DMA channel */ + ROM_DMA_CH2 = ROM_DMAREQ_UART1_RX, + ROM_DMAREQ_UART1_TX, /*!< UART1 transmit DMA channel */ + ROM_DMA_CH3 = ROM_DMAREQ_UART1_TX, + ROM_DMAREQ_UART2_RX, /*!< UART2 receive DMA channel */ + ROM_DMA_CH4 = ROM_DMAREQ_UART2_RX, + ROM_DMAREQ_UART2_TX, /*!< UART2 transmit DMA channel */ + ROM_DMA_CH5 = ROM_DMAREQ_UART2_TX, + ROM_DMAREQ_UART3_RX, /*!< UART3 receive DMA channel */ + ROM_DMA_CH6 = ROM_DMAREQ_UART3_RX, + ROM_DMAREQ_UART3_TX, /*!< UART3 transmit DMA channel */ + ROM_DMA_CH7 = ROM_DMAREQ_UART3_TX, + ROM_DMAREQ_SPI0_RX, /*!< SPI0 receive DMA channel */ + ROM_DMA_CH8 = ROM_DMAREQ_SPI0_RX, + ROM_DMAREQ_SPI0_TX, /*!< SPI0 transmit DMA channel */ + ROM_DMA_CH9 = ROM_DMAREQ_SPI0_TX, + ROM_DMAREQ_SPI1_RX, /*!< SPI1 receive DMA channel */ + ROM_DMA_CH10 = ROM_DMAREQ_SPI1_RX, + ROM_DMAREQ_SPI1_TX, /*!< SPI1 transmit DMA channel */ + ROM_DMA_CH11 = ROM_DMAREQ_SPI1_TX, + ROM_DMAREQ_I2C0_SLAVE, /*!< I2C0 Slave DMA channel */ + ROM_DMA_CH12 = ROM_DMAREQ_I2C0_SLAVE, + ROM_DMAREQ_I2C0_MASTER, /*!< I2C0 Master DMA channel */ + ROM_DMA_CH13 = ROM_DMAREQ_I2C0_MASTER, + ROM_DMAREQ_I2C1_SLAVE, /*!< I2C1 Slave DMA channel */ + ROM_DMA_CH14 = ROM_DMAREQ_I2C1_SLAVE, + ROM_DMAREQ_I2C1_MASTER, /*!< I2C1 Master DMA channel */ + ROM_DMA_CH15 = ROM_DMAREQ_I2C1_MASTER, + ROM_DMAREQ_I2C2_SLAVE, /*!< I2C2 Slave DMA channel */ + ROM_DMA_CH16 = ROM_DMAREQ_I2C2_SLAVE, + ROM_DMAREQ_I2C2_MASTER, /*!< I2C2 Master DMA channel */ + ROM_DMA_CH17 = ROM_DMAREQ_I2C2_MASTER, + ROM_DMAREQ_I2C0_MONITOR, /*!< I2C0 Monitor DMA channel */ + ROM_DMA_CH18 = ROM_DMAREQ_I2C0_MONITOR, + ROM_DMAREQ_I2C1_MONITOR, /*!< I2C1 Monitor DMA channel */ + ROM_DMA_CH19 = ROM_DMAREQ_I2C1_MONITOR, + ROM_DMAREQ_I2C2_MONITOR, /*!< I2C2 Monitor DMA channel */ + ROM_DMA_CH20 = ROM_DMAREQ_I2C2_MONITOR, + ROM_RESERVED_SPARE_DMA, + ROM_DMAREG_CH21 = ROM_RESERVED_SPARE_DMA, + ROM_DMALASTCHANNEL = ROM_RESERVED_SPARE_DMA, +} ROM_DMA_CHID_T; + +/** @brief Descriptor status tags */ +typedef enum { + ROM_DMA_DESC_STS_INVALID, /*!< DMA descriptor is invalid */ + ROM_DMA_DESC_STS_QUEUEING, /*!< DMA descriptor is being queued */ + ROM_DMA_DESC_STS_READY, /*!< DMA descriptor ready status */ + ROM_DMA_DESC_STS_BUSY, /*!< DMA descriptor busy status */ + ROM_DMA_DESC_STS_SPENT, /*!< DMA descriptor spent (complete) status */ + ROM_DMA_DESC_STS_ABORT, /*!< DMA descriptor aborted status */ + ROM_DMA_DESC_STS_ERROR, /*!< DMA descriptor error status */ +} ROM_DMA_DESC_STS_T; + +/** @brief DMA transfer descriptor - must be 16 byte aligned */ +struct ROM_DMA_DESC; + +typedef PRE_PACK struct POST_PACK { + uint32_t xfercfg; /*!< DMA Configuration register */ + uint32_t src; /*!< DMA source address */ + uint32_t dest; /*!< DMA destination address */ + struct ROM_DMA_DESC *pNextLink; /*!< Pointer to next descriptor link in a chain, NULL to end */ + + struct ROM_DMA_DESC *pNextChain; /*!< Pointer to next descriptor chain to process, NULL to end */ + + uint32_t status; /*!< Descriptor's current status (ROM_DMA_DESC_STS_T) */ + void *pUserData; /*!< Pointer to user data for the descriptor (chain) */ + uint16_t savedXferSize; /*!< Saved transfer size for this descriptor */ + uint16_t reserved1[1]; /*!< Needed to maintain alignment at 16 bytes */ +} ROM_DMA_DESC_T; + +/** @brief DMA controller callback IDs */ +typedef enum { + ROM_DMA_XFERCOMPLETE_CB = 0, /*!< Callback ID for DMA transfer descriptor chain complete */ + ROM_DMA_XFERDESCCOMPLETE_CB, /*!< Callback ID for DMA transfer descriptor complete */ + ROM_DMA_XFERERROR_CB, /*!< Callback ID for DMA transfer error occurance */ +} ROM_DMA_CALLBACK_T; + +struct ROM_DMA_QUEUE; + +/** @brief DMA controller transfer descriptor chain complete callback + * This callback is called from the DMA controller handler when the DMA controller + * has completed a complete transfer descriptor chain, the chain has stopped due to an error, + * or the chain has been aborted. The callback is only called if it has been registered. + */ +typedef void (*dmaTransferCompleteCB)(ROM_DMA_HANDLE_T spimHandle, struct ROM_DMA_QUEUE *pQueue, + ROM_DMA_DESC_T *pTranDesc); + +/** @brief DMA controller transfer descriptor complete callback + * This callback is called from the DMA controller handler when the DMA controller + * has completed a transfer descriptor. The callback is only called if it has been registered + * and the transfer descriptor has been enabled for interrupt operation with the fireDescCB option. + */ +typedef void (*dmaTransferDescCompleteCB)(ROM_DMA_HANDLE_T spimHandle, struct ROM_DMA_QUEUE *pQueue, + ROM_DMA_DESC_T *pTranDesc); + +/** @brief DMA controller transfer descriptor error callback + * This callback is called from the DMA controller handler when and error has occured in the + * DMA transfer. The callback is only called if it has been registered and the transfer descriptor has + * been enabled for interrupt operation. + */ +typedef void (*dmaTransferErrorCB)(ROM_DMA_HANDLE_T spimHandle, struct ROM_DMA_QUEUE *pQueue, ROM_DMA_DESC_T *pTranDesc); + +/** @brief DMA transfer queue - must be 16 byte aligned */ +typedef PRE_PACK struct POST_PACK { + dmaTransferCompleteCB dmaCompCB; /*!< Transfer descriptor chain completion callback */ + dmaTransferDescCompleteCB dmaDescCompCB; /*!< Transfer descriptor completion callback */ + dmaTransferErrorCB dmaErrorCB; /*!< Transfer error callback */ + ROM_DMA_DESC_T *pDescEnd; /*!< Pointer to last descriptor chain */ + ROM_DMA_DESC_T *pDescNext; /*!< Pointer to next descriptor chain to process */ + ROM_DMA_DESC_T *pDescPop; /*!< Pointer to first descriptor chain */ + struct ROM_DMA_QUEUE *pQueueHead; /*!< Pointer to next queue descriptor */ + + uint8_t dmaCh; /*!< DMA channel mapped to this queue (ROM_DMA_CHID_T) */ + uint8_t queueSt; /*!< Current state of this queue (ROM_DMA_QUEUE_STATES_T) */ + uint8_t reserved[2]; +} ROM_DMA_QUEUE_T; + +/** @brief DMA burst transfer sizing + */ +typedef enum { + ROM_DMA_BURSTPOWER_1 = 0, /*!< Set DMA burst size to 1 data transfer */ + ROM_DMA_BURSTPOWER_2, /*!< Set DMA burst size to 2 data transfer */ + ROM_DMA_BURSTPOWER_4, /*!< Set DMA burst size to 4 data transfer */ + ROM_DMA_BURSTPOWER_8, /*!< Set DMA burst size to 8 data transfer */ + ROM_DMA_BURSTPOWER_16, /*!< Set DMA burst size to 16 data transfer */ + ROM_DMA_BURSTPOWER_32, /*!< Set DMA burst size to 32 data transfer */ + ROM_DMA_BURSTPOWER_64, /*!< Set DMA burst size to 64 data transfer */ + ROM_DMA_BURSTPOWER_128, /*!< Set DMA burst size to 128 data transfer */ + ROM_DMA_BURSTPOWER_256, /*!< Set DMA burst size to 256 data transfer */ + ROM_DMA_BURSTPOWER_512, /*!< Set DMA burst size to 512 data transfer */ + ROM_DMA_BURSTPOWER_1024 /*!< Set DMA burst size to 1024 data transfer */ +} ROM_DMA_BURSTPOWER_T; + +/** @brief DMA transfer channel setup structure (use this structure as const if possible) */ +typedef PRE_PACK struct POST_PACK { + uint32_t periphReq : 1; /*!< 0 = hardware trigger request, !0 = peripheral request */ + uint32_t triggerPolHi : 1; /*!< 0 = low trigger polarity, !0 = high polarity, only valid if triggerReq == 0 */ + uint32_t triggerLevel : 1; /*!< 0 = edge triggered, !0 = level triggered, only valid if triggerReq == 0 */ + uint32_t triggerBurst : 1; /*!< 0 = single data transfer, !0 = burst data transfer, only valid if triggerReq == 0 */ + uint32_t burstSize : 4; /*!< Burst data transfer size, only valid if triggerReq == 0 (ROM_DMA_BURSTPOWER_T) */ + uint32_t srcBurstWrap : 1; /*!< 0 = disable source burst wrap, !0 = enable source burst wrap */ + uint32_t dstBurstWrap : 1; /*!< 0 = disable destination burst wrap, !0 = enable destination burst wrap */ + uint32_t channelPrio : 3; /*!< 0 = highest channel priority, 7 = lowest channel priority */ + uint32_t reserved : 3; +} ROM_DMA_CHAN_CFG_T; + +/** @brief DMA transfer width values + */ +typedef enum { + ROM_DMA_WIDTH_1 = 0, /*!< Transfer size of data is 8-bits (1 byte) */ + ROM_DMA_WIDTH_2, /*!< Transfer size of data is 16-bits (1 byte) */ + ROM_DMA_WIDTH_4, /*!< Transfer size of data is 32-bits (1 byte) */ +} ROM_DMA_WIDTH_T; + +/** @brief DMA source and destination address increment values + */ +typedef enum { + ROM_DMA_ADDRINC_0X = 0, /*!< No address increment, useful to reading and writing FIFOs */ + ROM_DMA_ADDRINC_1X, /*!< Address increment by width */ + ROM_DMA_ADDRINC_2X, /*!< Address increment by 2x width */ + ROM_DMA_ADDRINC_4X, /*!< Address increment by 4x width */ +} ROM_DMA_ADDRINC_T; + +/** @brief DMA transfer setup structure */ +typedef PRE_PACK struct POST_PACK { + void *src; /*!< DMA source address */ + void *dest; /*!< DMA destination address */ + void *pUserData; /*!< Pointer to user data for the descriptor (chain), this only matters for the head descriptor in a chain */ + uint16_t xferCount; /*!< DMA transfer size in size of data width (not bytes). 1 to 1024 */ + uint8_t swTrig; /*!< !0 = Software trigger of channel when descriptor is started (not recommended) */ + uint8_t clrTrig; /*!< !0 = Clear trigger when descriptor is completed */ + uint8_t fireDescCB; /*!< !0 = DMA interrupt fires after this descriptor is complete and calls descriptor complete callback */ + uint8_t enabCirc; /*!< !0 = Enable circular buffer support : Will disable completion callback */ + uint8_t width; /*!< Data transfer width (ROM_DMA_WIDTH_T) */ + uint8_t srcInc; /*!< Source address incremention (ROM_DMA_ADDRINC_T) */ + uint8_t dstInc; /*!< Destination address incremention (ROM_DMA_ADDRINC_T) */ + uint8_t dmaCh; /*!< Configured DMA channel mapped to this descriptor (ROM_DMA_CHID_T) */ + uint8_t stallDesc; /*!< Stalls this descriptor using CFGVALID before transfer, must use SETVALID to restart */ + uint8_t reserved; +} ROM_DMA_XFERDESC_CFG_T; + +/** @brief SPI master initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Pointer to where the DMA peripheral is located */ + uint32_t sramBase; /*!< Pointer to memory used for DMA descriptor storage, must be 512 byte aligned */ +} ROM_DMA_INIT_T; + +/** @brief Queue operating states + * These are the possible states of the DMA descriptor channel queue. + */ +typedef enum { + ROM_QUEUE_ST_IDLE = 0, /*!< DMA queue is idle. Use ROM_SET_QUEUE_START to start */ + ROM_QUEUE_ST_RUNNING, /*!< DMA queue is processing descriptor chains */ + ROM_QUEUE_ST_ERROR /*!< DMA queue is stoipped due to an error. Use ROM_SET_QUEUE_START to restart at next descriptor chain */ +} ROM_DMA_QUEUE_STATES_T; + +/** @brief SPI master ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + /* DMA driver initialization */ + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of DMA controller driver */ + ROM_DMA_HANDLE_T (*Init)(void *mem, const ROM_DMA_INIT_T *pInit); /*!< Initializes the DMA controller driver and peripheral */ + + /* DMA channel setup, channel queue setup, and channel callback registration */ + ErrorCode_t (*SetupChannel)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_CHAN_CFG_T *pCfg, uint8_t dmaCh); /*!< Configures a DMA channel */ + ErrorCode_t (*InitQueue)(ROM_DMA_HANDLE_T pHandle, uint8_t dmaCh, ROM_DMA_QUEUE_T *pQueue); /*!< Initializes a transfer descriptor queue for a channel */ + void (*RegisterQueueCallback)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, uint32_t cbIndex, void *pCB); /*!< Registers an DMA controller callback for a queue */ + + /* DMA descriptor chain build and status support */ + ErrorCode_t (*BuildDescriptorChain)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_XFERDESC_CFG_T *pXferCfg, + ROM_DMA_DESC_T *pDesc, ROM_DMA_DESC_T *pDescPrev); /*!< Builds a transfer descriptor chain from the passed settings */ + uint32_t (*GetTransferCount)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_DESC_T *pDesc); /*!< Returns the number of items transferred on the last descriptor chain (spent status only) */ + void (*UnstallDescriptorChain)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Unstalls a descriptor chain that has been setup using the stallDesc option */ + + /* DMA queue management */ + void (*QueueDescriptor)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, ROM_DMA_DESC_T *pDescChainHead); /*!< Queues a transfer descriptor chain */ + ROM_DMA_DESC_STS_T (*GetQueuePopDescriptorStatus)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Returns current status of next descriptro to be popped from the queue, ROM_DMA_DESC_STS_INVALID if no descriptors exist to be popped */ + ROM_DMA_DESC_T * (*UnQueueDescriptor)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T * pQueue); /*!< Pops (unqueues) an expired transfer descriptor from the queue - expired descriptors are in spent, error, or abort states */ + ErrorCode_t (*StartQueue)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Starts or restarts a queue at the next descriptor chain */ + ErrorCode_t (*StopQueue)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Stops DMA and aborts current descriptor chain being processed in queue, call StartQueue to restart at the next descriptor chain */ + void (*FlushQueue)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Stops DMA and completely flushes a transfer queue, queue is completely reset */ + uint8_t (*GetQueueState)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Returns the current queue state (ROM_DMA_QUEUE_STATES_T) */ + + /* Misc */ + void (*ForceTrigger)(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); /*!< Forces a DMA transfer to trigger */ + + /* DMA queue and transfer handler - must be called from DMA interrupt or from background as fast as possible */ + void (*DMAHandler)(ROM_DMA_HANDLE_T pHandle); /*!< DMA transfer (interrupt) handler */ + + /* Driver version */ + uint32_t (*GetDriverVersion)(void); +} ROM_DMAALTD_API_T; + +/** + * @} + */ + +extern const ROM_DMAALTD_API_T dmaalt_api; // so application program can access pointer to +// function table + +#endif /* __HW_DMAALTD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2c_common.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2c_common.h new file mode 100644 index 0000000000000000000000000000000000000000..19cc07e1d1c8c205f7e6a636725098e4df714f67 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2c_common.h @@ -0,0 +1,201 @@ +/* + * @brief I2C ROM API declarations and functions + * + * @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 __HW_I2C_COMMON_H_ +#define __HW_I2C_COMMON_H_ + +/** + * @brief I2C register block structure + */ +typedef struct { /* I2C0 Structure */ + volatile uint32_t CFG; /*!< I2C Configuration Register common for Master, Slave and Monitor */ + volatile uint32_t STAT; /*!< I2C Status Register common for Master, Slave and Monitor */ + volatile uint32_t INTENSET; /*!< I2C Interrupt Enable Set Register common for Master, Slave and Monitor */ + volatile uint32_t INTENCLR; /*!< I2C Interrupt Enable Clear Register common for Master, Slave and Monitor */ + volatile uint32_t TIMEOUT; /*!< I2C Timeout value Register */ + volatile uint32_t CLKDIV; /*!< I2C Clock Divider Register */ + volatile uint32_t INTSTAT; /*!< I2C Interrupt Status Register */ + volatile uint32_t RESERVED0; + volatile uint32_t MSTCTL; /*!< I2C Master Control Register */ + volatile uint32_t MSTTIME; /*!< I2C Master Time Register for SCL */ + volatile uint32_t MSTDAT; /*!< I2C Master Data Register */ + volatile uint32_t RESERVED1[5]; + volatile uint32_t SLVCTL; /*!< I2C Slave Control Register */ + volatile uint32_t SLVDAT; /*!< I2C Slave Data Register */ + volatile uint32_t SLVADR[4]; /*!< I2C Slave Address Registers */ + volatile uint32_t SLVQUAL0; /*!< I2C Slave Address Qualifier 0 Register */ + volatile uint32_t RESERVED2[9]; + volatile uint32_t MONRXDAT; /*!< I2C Monitor Data Register */ +} LPC_I2C_T; + +/* + * @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 */ + +#endif /* __HW_I2C_COMMON_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.c new file mode 100644 index 0000000000000000000000000000000000000000..e5578f04a490ec825cb1fb893f452978d2fd61ca --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.c @@ -0,0 +1,369 @@ +/* + * @brief I2C master ROM API declarations and functions + * + * @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 +#include +#include "hw_i2cmd.h" + +#define DRVVERSION 0x0100 + +/* Private data structure used for the I2C master driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_I2C_T *base; /*!< Base address of I2C peripheral to use */ + i2cMasterCompleteCB pXferCompCB; /*!< Transfer complete callback */ + i2cMasterTransmitStartCB pTranStartCb; /*!< Transmit data start callback */ + i2cMasterReceiveStartCB pTranRecvCb; /*!< Receive data start callback */ + ROM_I2CM_XFER_T *pXfer; /*!< Pointer to current transfer */ + ErrorCode_t pendingStatus; /*!< Pending master transfer status before clocking transfer */ + uint16_t sendIdx; + uint16_t recvIdx; +} I2CM_DATACONTEXT_T; + +#define _rom_i2cmEnable(pI2C) (pI2C->CFG |= I2C_CFG_MSTEN); +#define _rom_i2cmGetMasterState(pI2C) ((pI2C->STAT & I2C_STAT_MSTSTATE) >> 1) + +/* Sets I2C Clock Divider registers */ +static void _rom_i2cmSetClockDiv(LPC_I2C_T *pI2C, uint32_t clkdiv) +{ + if ((clkdiv >= 1) && (clkdiv <= 65536)) { + pI2C->CLKDIV = clkdiv - 1; + } + else { + pI2C->CLKDIV = 0; + } +} + +/* Sets HIGH and LOW duty cycle registers */ +static void _rom_i2cmSetDutyCycle(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); +} + +// ********************************************************** +uint32_t i2cm_get_mem_size(void) +{ + return sizeof(I2CM_DATACONTEXT_T); +} + +ROM_I2CM_HANDLE_T i2cm_init(void *mem, const ROM_I2CM_INIT_T *pInit) +{ + I2CM_DATACONTEXT_T *pDrv; + + /* Verify alignment is at least 4 bytes */ + if (((uint32_t) mem & 0x3) != 0) { + return NULL; + } + + pDrv = (I2CM_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(I2CM_DATACONTEXT_T)); + + /* Save base of peripheral and pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_I2C_T *) pInit->base; + + /* Pick a safe clock divider until clock rate is setup */ + _rom_i2cmSetClockDiv(pDrv->base, 8); + + /* Clear pending master statuses */ + pDrv->base->STAT = (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR); + + /* Enable I2C master interface */ + _rom_i2cmEnable(pDrv->base); + + return pDrv; +} + +uint32_t i2cm_set_clock_rate(ROM_I2CM_HANDLE_T pHandle, uint32_t inRate, uint32_t i2cRate) +{ + uint32_t scl, div; + I2CM_DATACONTEXT_T *pDrv = (I2CM_DATACONTEXT_T *) pHandle; + + /* Determine the best I2C clock dividers to generate the target I2C master clock */ + /* The maximum SCL and SCH dividers are 7, for a maximum divider set of 14 */ + /* The I2C master divider is between 1 and 65536. */ + + /* Pick a main I2C divider that allows centered SCL/SCH dividers */ + div = inRate / (i2cRate << 3); + if (div == 0) { + div = 1; + } + _rom_i2cmSetClockDiv(pDrv->base, div); + + /* Determine SCL/SCH dividers */ + scl = inRate / (div * i2cRate); + _rom_i2cmSetDutyCycle(pDrv->base, (scl >> 1), (scl - (scl >> 1))); + + return inRate / (div * scl); +} + +void i2cm_register_callback(ROM_I2CM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB) +{ + I2CM_DATACONTEXT_T *pDrv = (I2CM_DATACONTEXT_T *) pHandle; + + if (cbIndex == ROM_I2CM_DATACOMPLETE_CB) { + pDrv->pXferCompCB = (i2cMasterCompleteCB) pCB; + } + else if (cbIndex == ROM_I2CM_DATATRANSMITSTART_CB) { + pDrv->pTranStartCb = (i2cMasterTransmitStartCB) pCB; + } + else if (cbIndex == ROM_I2CM_DATATRECEIVESTART_CB) { + pDrv->pTranRecvCb = (i2cMasterReceiveStartCB) pCB; + } +} + +ErrorCode_t i2cm_transfer(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_XFER_T *pXfer) +{ + I2CM_DATACONTEXT_T *pDrv = (I2CM_DATACONTEXT_T *) pHandle; + + /* Is transfer NULL? */ + if (pXfer == NULL) { + return ERR_I2C_PARAM; + } + + /* I2C master controller should be pending and idle */ + if ((pDrv->base->STAT & I2C_STAT_MSTPENDING) == 0) { + pXfer->status = ERR_I2C_GENERAL_FAILURE; + return ERR_I2C_GENERAL_FAILURE; + } + if (_rom_i2cmGetMasterState(pDrv->base) != I2C_STAT_MSTCODE_IDLE) { + pXfer->status = ERR_I2C_GENERAL_FAILURE; + return ERR_I2C_GENERAL_FAILURE; + } + + /* Save transfer descriptor */ + pDrv->pXfer = pXfer; + pXfer->status = ERR_I2C_BUSY; + pDrv->sendIdx = 0; + pDrv->recvIdx = 0; + + /* Pending status for completion of trasnfer */ + pDrv->pendingStatus = ERR_I2C_GENERAL_FAILURE; + + /* Clear controller state */ + pDrv->base->STAT = (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR); + + /* Will always transisiton to idle at start or end of transfer */ + if (pXfer->txSz) { + /* Call transmit start callback to setup TX DMA if needed */ + if (pDrv->pTranStartCb) { + pDrv->pTranStartCb(pHandle, pXfer); + } + + /* Start transmit state */ + pDrv->base->MSTDAT = (uint32_t) (pXfer->slaveAddr << 1); + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTART; + } + else if (pXfer->rxSz) { + /* Start receive state with start ot repeat start */ + pDrv->base->MSTDAT = (uint32_t) (pXfer->slaveAddr << 1) | 0x1; + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTART; + + /* Call receive start callback to setup RX DMA if needed */ + if (pDrv->pTranRecvCb) { + pDrv->pTranRecvCb(pHandle, pXfer); + } + } + else { + /* No data - either via data callbacks or a slave query only */ + pDrv->base->MSTDAT = (uint32_t) (pXfer->slaveAddr << 1); + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTART; + } + + /* Enable supported master interrupts */ + pDrv->base->INTENSET = (I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | + I2C_INTENSET_MSTSTSTPERR); + + /* Does the driver need to block? */ + if ((pXfer->flags & ROM_I2CM_FLAG_BLOCKING) != 0) { + while (pXfer->status == ERR_I2C_BUSY) { + i2cm_transfer_handler(pHandle); + } + } + + return pXfer->status; +} + +// Otime = "optimize for speed of code execution" +// ...add this pragma 1 line above the interrupt service routine function. +void i2cm_transfer_handler(ROM_I2CM_HANDLE_T pHandle) +{ + I2CM_DATACONTEXT_T *pDrv = (I2CM_DATACONTEXT_T *) pHandle; + ROM_I2CM_XFER_T *pXfer = pDrv->pXfer; + + uint32_t status = pDrv->base->STAT; + + if (status & I2C_STAT_MSTRARBLOSS) { + /* Master Lost Arbitration */ + /* Set transfer status as Arbitration Lost */ + pDrv->pendingStatus = ERR_I2C_LOSS_OF_ARBRITRATION; + + /* Clear Status Flags */ + pDrv->base->STAT = I2C_STAT_MSTRARBLOSS; + + pDrv->base->INTENCLR = (I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | + I2C_INTENSET_MSTSTSTPERR); + pXfer->status = pDrv->pendingStatus; + if (pDrv->pXferCompCB != NULL) { + pDrv->pXferCompCB(pHandle, pXfer); + } + } + else if (status & I2C_STAT_MSTSTSTPERR) { + /* Master Start Stop Error */ + /* Set transfer status as Bus Error */ + pDrv->pendingStatus = ERR_I2C_GENERAL_FAILURE; + + /* Clear Status Flags */ + pDrv->base->STAT = I2C_STAT_MSTSTSTPERR; + + pDrv->base->INTENCLR = (I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | + I2C_INTENSET_MSTSTSTPERR); + pXfer->status = pDrv->pendingStatus; + if (pDrv->pXferCompCB != NULL) { + pDrv->pXferCompCB(pHandle, pXfer); + } + } + else if (status & I2C_STAT_MSTPENDING) { + /* Master is Pending */ + /* Branch based on Master State Code */ + switch (_rom_i2cmGetMasterState(pDrv->base)) { + case I2C_STAT_MSTCODE_IDLE: /* Master idle */ + /* Idle state is only called on completion of transfer */ + /* Disable interrupts */ + pDrv->base->INTENCLR = (I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | + I2C_INTENSET_MSTSTSTPERR); + + /* Update status and call transfer completion callback */ + pXfer->status = pDrv->pendingStatus; + if (pDrv->pXferCompCB != NULL) { + pDrv->pXferCompCB(pHandle, pXfer); + } + break; + + case I2C_STAT_MSTCODE_RXREADY: /* Receive data is available */ + if (((pXfer->flags & ROM_I2CM_FLAG_DMARX) != 0) && (pXfer->rxSz > 0)) { + /* Use DMA for receive */ + pDrv->base->MSTCTL = I2C_MSTCTL_MSTDMA; + pXfer->flags &= ~ROM_I2CM_FLAG_DMARX; + pXfer->rxSz = 0; + return; + } + else if (pXfer->rxSz) { + uint8_t *p8 = pXfer->rxBuff; + p8[pDrv->recvIdx] = (uint8_t) pDrv->base->MSTDAT & 0xFF; + pDrv->recvIdx++; + pXfer->rxSz--; + } + + if (pXfer->rxSz) { + pDrv->base->MSTCTL = I2C_MSTCTL_MSTCONTINUE; + } + else { + /* Last byte to receive, send stop after byte received */ + pDrv->base->MSTCTL = I2C_MSTCTL_MSTCONTINUE | I2C_MSTCTL_MSTSTOP; + pDrv->pendingStatus = LPC_OK; + } + break; + + case I2C_STAT_MSTCODE_TXREADY: /* Master Transmit available */ + if (((pXfer->flags & ROM_I2CM_FLAG_DMATX) != 0) && (pXfer->txSz > 0)) { + /* Use DMA for transmit */ + pDrv->base->MSTCTL = I2C_MSTCTL_MSTDMA; + pXfer->flags &= ~ROM_I2CM_FLAG_DMATX; + pXfer->txSz = 0; + return; + } + else if (pXfer->txSz) { + uint8_t *p8 = (uint8_t *) pXfer->txBuff; + /* If Tx data available transmit data and continue */ + pDrv->base->MSTDAT = (uint32_t) p8[pDrv->sendIdx]; + pDrv->base->MSTCTL = I2C_MSTCTL_MSTCONTINUE; + pDrv->sendIdx++; + pXfer->txSz--; + } + else if (pXfer->rxSz == 0) { + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTOP; + pDrv->pendingStatus = LPC_OK; + } + else { + /* Start receive state with repeat start */ + pDrv->base->MSTDAT = (uint32_t) (pXfer->slaveAddr << 1) | 0x1; + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTART; + + /* Call receive start callback to setup RX DMA if needed */ + if (pDrv->pTranRecvCb) { + pDrv->pTranRecvCb(pHandle, pXfer); + } + } + break; + + case I2C_STAT_MSTCODE_NACKADR: /* Slave address was NACK'ed */ + /* Set transfer status as NACK on address */ + pDrv->pendingStatus = ERR_I2C_SLAVE_NOT_ADDRESSED; + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTOP; + break; + + case I2C_STAT_MSTCODE_NACKDAT: /* Slave data was NACK'ed */ + /* Set transfer status as NACK on data */ + pDrv->pendingStatus = ERR_I2C_NAK; + pDrv->base->MSTCTL = I2C_MSTCTL_MSTSTOP; + break; + + default: + /* Illegal I2C master state machine case. This should never happen. + Disable and re-enable controller to clear state machine */ + pDrv->pendingStatus = ERR_I2C_GENERAL_FAILURE; + break; + } + } +} + +uint32_t i2cm_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.h new file mode 100644 index 0000000000000000000000000000000000000000..f04a407c5f2bc11e95dca6416e3be002156b9a2e --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd.h @@ -0,0 +1,55 @@ +/* + * @brief I2C master ROM API declarations and functions + * + * @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 __HW_I2CMD_H +#define __HW_I2CMD_H + +#include "error.h" +#include "hw_i2cmd_rom_api.h" + +// *** I2C functions called by Application Program *** +uint32_t i2cm_get_mem_size(void); + +ROM_I2CM_HANDLE_T i2cm_init(void *mem, const ROM_I2CM_INIT_T *pInit); + +uint32_t i2cm_set_clock_rate(ROM_I2CM_HANDLE_T pHandle, uint32_t inRate, uint32_t i2cRate); + +void i2cm_register_callback(ROM_I2CM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); + +ErrorCode_t i2cm_transfer(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_XFER_T *pXfer); + +void i2cm_transfer_handler(ROM_I2CM_HANDLE_T pHandle); + +uint32_t i2cm_get_driver_version(void); + +// *** + +#endif /* __HW_I2CMD_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..07a3e152591926c7e357d716d02937ab14f7bf42 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.c @@ -0,0 +1,44 @@ +/* + * @brief I2C master ROM API declarations and functions + * + * @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 "hw_i2cmd.h" + +// This creates a table with the addresses of all the I2C functions +// This table of function pointers is the API interface. +const ROM_I2CMD_API_T i2cm_api = { + &i2cm_get_mem_size, + &i2cm_init, + &i2cm_set_clock_rate, + &i2cm_register_callback, + &i2cm_transfer, + &i2cm_transfer_handler, + &i2cm_get_driver_version, +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..0962f875fcd17ba8ce14524e7f6ff76f1d06b84d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmd_rom_api.h @@ -0,0 +1,127 @@ +/* + * @brief I2C master ROM API declarations and functions + * + * @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 __HW_I2CMD_ROM_API_H +#define __HW_I2CMD_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_i2c_common.h" + +/** @defgroup ROMAPI_I2CM I2C master ROM driver functions and definitions + * @ingroup ROMAPI_I2CM_WRAPPER + * @{ + */ + +/** @brief I2C master handle type */ +typedef void *ROM_I2CM_HANDLE_T; + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a I2C master + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_I2CM_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_I2CM_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief I2C master optional transfer flags */ +#define ROM_I2CM_FLAG_BLOCKING (1UL << 31) /*!< Transfer function will block until complete */ +#define ROM_I2CM_FLAG_DMATX (1UL << 30) /*!< DMA will be used for TX, requires DMA setup outside of the driver */ +#define ROM_I2CM_FLAG_DMARX (1UL << 29) /*!< DMA will be used for RX, requires DMA setup outside of the driver */ +#define ROM_I2CM_FLAG_USERBITS (0xFFFF) /*!< Application can safely use the flag bits designated by this mask */ + +/** @brief Master transfer descriptor */ +typedef PRE_PACK struct POST_PACK { + const void *txBuff; /*!< Pointer to array of bytes to be transmitted */ + void *rxBuff; /*!< Pointer memory where bytes received from I2C be stored */ + volatile ErrorCode_t status; /*!< Packed status of the current I2C transfer (ErrorCode_t), must be 32-bits */ + uint32_t flags; /*!< Optional transfer flags */ + uint16_t txSz; /*!< Number of bytes in transmit array, if 0 only receive transfer will be performed */ + uint16_t rxSz; /*!< Number of bytes to receive, if 0 only transmission we be performed */ + uint16_t slaveAddr; /*!< 7-bit I2C Slave address */ + uint16_t reserved; /*!< Reserved for alignment */ +} ROM_I2CM_XFER_T; + +/** I2C master callback IDs */ +typedef enum { + ROM_I2CM_DATACOMPLETE_CB = 0, /*!< Callback ID for I2C master data transfer complete */ + ROM_I2CM_DATATRANSMITSTART_CB, /*!< Callback ID for I2C master transmit start */ + ROM_I2CM_DATATRECEIVESTART_CB /*!< Callback ID for I2C master receive start */ +} ROM_I2CM_CALLBACK_T; + +/** @brief I2C master transfer complete callback prototype + * The I2C master state machine will call this function when the transfer completes normally + * or due to an error (NAK, arbitration, etc.). + */ +typedef void (*i2cMasterCompleteCB)(ROM_I2CM_HANDLE_T i2cmHandle, ROM_I2CM_XFER_T *pXfer); + +/** @brief I2C master data receive start callback + * The I2C master state machine will call this optional function prior to data transfer. + * The callback can be used to setup DMA or alter the receive buffer size. The callback is + * only called if it has been registered and the receive size (rxSz) in the transfer descriptor + * is 0. + */ +typedef void (*i2cMasterReceiveStartCB)(ROM_I2CM_HANDLE_T i2cmHandle, ROM_I2CM_XFER_T *pXfer); + +/** @brief I2C master data transmit start callback + * The I2C master state machine will call this optional function prior to data transfer. + * The callback can be used to setup DMA or alter the transmit buffer size. The callback is + * only called if it has been registered and the transmit size (txSz) in the transfer descriptor + * is 0. + */ +typedef void (*i2cMasterTransmitStartCB)(ROM_I2CM_HANDLE_T i2cmHandle, ROM_I2CM_XFER_T *pXfer); + +/** @brief I2C master initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Base address of I2C peripheral to use */ +} ROM_I2CM_INIT_T; + +/** @brief I2C master ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of I2C master driver */ + ROM_I2CM_HANDLE_T (*Init)(void *mem, const ROM_I2CM_INIT_T *pInit); /*!< Initializes the I2C master driver and peripheral */ + uint32_t (*SetClockRate)(ROM_I2CM_HANDLE_T pHandle, uint32_t inRate, uint32_t i2cRate); /*!< Sets the I2C master clock rate */ + void (*RegisterCallback)(ROM_I2CM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); /*!< Registers an I2C master callback */ + ErrorCode_t (*Transfer)(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_XFER_T *pXfer); /*!< Perform or start and I2C master transfer */ + void (*TransferHandler)(ROM_I2CM_HANDLE_T pHandle); /*!< I2C master transfer (interrupt) handler */ + uint32_t (*GetDriverVersion)(void); +} ROM_I2CMD_API_T; + +/** + * @} + */ + +extern const ROM_I2CMD_API_T i2cm_api; // so application program can access pointer to +// function table + +#endif /* __HW_I2CMD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.c new file mode 100644 index 0000000000000000000000000000000000000000..775200c1fcbda374a7c1094f2fa262c753e8349c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.c @@ -0,0 +1,208 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 +#include +#include "hw_i2cmond.h" + +#define DRVVERSION 0x0100 + +/* Private data structure used for the I2C monitor driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_I2C_T *base; /*!< Base address of I2C peripheral to use */ + i2cMonCapReadyCB pCapCompCB; /*!< Capture complete callback */ + i2cMonSetupDMACB pDmaSetupCB; /*!< DMA setup callback */ + ROM_I2CMON_CAP_T *pCap; /*!< Pointer to current capture descriptor */ + ErrorCode_t pendingStatus; /*!< Pending monitor transfer status before clocking transfer */ +} I2CMON_DATACONTEXT_T; + +void i2cmon_transfer_handler(ROM_I2CMON_HANDLE_T pHandle) +; + +// ********************************************************** +uint32_t i2cmon_get_mem_size(void) +{ + return sizeof(I2CMON_DATACONTEXT_T); +} + +ROM_I2CMON_HANDLE_T i2cmon_init(void *mem, const ROM_I2CMON_INIT_T *pInit) +{ + I2CMON_DATACONTEXT_T *pDrv; + uint32_t reg; + + /* Verify alignment is at least 4 bytes */ + if (((uint32_t) mem & 0x3) != 0) { + return NULL; + } + + pDrv = (I2CMON_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(I2CMON_DATACONTEXT_T)); + + /* Save base of peripheral and pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_I2C_T *) pInit->base; + + /* Clear pending monitor statuses */ + pDrv->base->STAT = (I2C_STAT_MONIDLE | I2C_STAT_MONOV); + while ((pDrv->base->STAT & I2C_STAT_MONRDY) != 0) { + /* Toss input data */ + reg = pDrv->base->MONRXDAT; + } + + /* Enable I2C monitor interface */ + reg = pDrv->base->CFG | I2C_CFG_MONEN; + if (pInit->stretch != 0) { + reg |= I2C_CFG_MONCLKSTR; + } + pDrv->base->CFG = reg; + + return pDrv; +} + +void i2cmom_register_callback(ROM_I2CMON_HANDLE_T pHandle, uint32_t cbIndex, void *pCB) +{ + I2CMON_DATACONTEXT_T *pDrv = (I2CMON_DATACONTEXT_T *) pHandle; + + if (cbIndex == ROM_I2CMON_CAPTUREREADY_CB) { + pDrv->pCapCompCB = (i2cMonCapReadyCB) pCB; + } + else if (cbIndex == ROM_I2CMON_DMASETUP_CB) { + pDrv->pDmaSetupCB = (i2cMonSetupDMACB) pCB; + } +} + +ErrorCode_t i2cmom_start_log(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CAP_T *pCap) +{ + I2CMON_DATACONTEXT_T *pDrv = (I2CMON_DATACONTEXT_T *) pHandle; + + /* I2C master controller should be pending and idle */ + if (pCap == NULL) { + return ERR_I2C_PARAM; + } + + /* Verify receive buffer alignment */ + if ((pCap->startBuff == NULL) || ((((uint32_t) pCap->startBuff) & 0x1) != 0) || (pCap->startBuffSz == 0)) { + pCap->status = ERR_I2C_PARAM; + return ERR_I2C_PARAM; + } + + pDrv->pCap = pCap; + pCap->capStartBuffSz = 0; + pDrv->pendingStatus = LPC_OK; + pCap->status = ERR_I2C_BUSY; + + if ((pCap->flags & ROM_I2CMON_FLAG_FLUSH) != 0) { + while ((pDrv->base->STAT & I2C_STAT_MONRDY) != 0) { + /* Toss input data */ + volatile uint32_t reg = pDrv->base->MONRXDAT; + } + } + + /* Clear controller state */ + pDrv->base->STAT = (I2C_STAT_MONIDLE | I2C_STAT_MONOV); + + if (((pCap->flags & ROM_I2CMON_FLAG_DMARX) != 0) && (pDrv->pDmaSetupCB)) { + pDrv->pDmaSetupCB(pHandle, pCap); + + /* Enable supported monitor interrupts */ + pDrv->base->INTENSET = (I2C_INTENSET_MONOV | I2C_INTENSET_MONIDLE); + } + else { + pCap->flags &= ~ROM_I2CMON_FLAG_DMARX; + + /* Enable supported monitor interrupts */ + pDrv->base->INTENSET = (I2C_INTENSET_MONRDY | I2C_INTENSET_MONOV | I2C_INTENSET_MONIDLE); + } + + /* Is transfer blocking? */ + if ((pCap->flags & ROM_I2CMON_FLAG_BLOCKING) != 0) { + while (pCap->status == ERR_I2C_BUSY) { + i2cmon_transfer_handler(pHandle); + } + } + + return pCap->status; +} + +// Otime = "optimize for speed of code execution" +// ...add this pragma 1 line above the interrupt service routine function. +void i2cmon_transfer_handler(ROM_I2CMON_HANDLE_T pHandle) +{ + I2CMON_DATACONTEXT_T *pDrv = (I2CMON_DATACONTEXT_T *) pHandle; + ROM_I2CMON_CAP_T *pCap = pDrv->pCap; + uint16_t data = 0, *pData; + + uint32_t status = pDrv->base->STAT; + + if (status & I2C_STAT_MONOV) { + /* Monitor data overflow */ + data = pDrv->base->MONRXDAT; + pDrv->pendingStatus = ERR_I2C_BUFFER_OVERFLOW; + + /* Clear Status Flags */ + pDrv->base->STAT = I2C_STAT_MONOV; + } + else if (status & I2C_STAT_MONRDY) { + /* Monitor ready */ + data = pDrv->base->MONRXDAT; + + /* Enough room to place this data? */ + if (pCap->capStartBuffSz >= pCap->startBuffSz) { + /* Data overflow */ + pDrv->pendingStatus = ERR_I2C_BUFFER_OVERFLOW; + } + else { + pData = (uint16_t *) pCap->startBuff; + + pData[pCap->capStartBuffSz] = data; + pCap->capStartBuffSz++; + } + } + + /* Capture complete? */ + if ((status & I2C_INTSTAT_MONIDLE) != 0) { + pDrv->base->INTENCLR = (I2C_INTENCLR_MONRDY | I2C_INTENCLR_MONOV | + I2C_INTENCLR_MONIDLE); + pCap->status = pDrv->pendingStatus; + if (pDrv->pCapCompCB) { + pDrv->pCapCompCB(pHandle, pCap); + } + } +} + +uint32_t i2cmon_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.h new file mode 100644 index 0000000000000000000000000000000000000000..d68e416b510217ec3bbcf4877b87f10f4a24527d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond.h @@ -0,0 +1,53 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 __HW_I2CMOND_H +#define __HW_I2CMOND_H + +#include "error.h" +#include "hw_i2cmond_rom_api.h" + +// *** I2C functions called by Application Program *** +uint32_t i2cmon_get_mem_size(void); + +ROM_I2CMON_HANDLE_T i2cmon_init(void *mem, const ROM_I2CMON_INIT_T *pInit); + +void i2cmom_register_callback(ROM_I2CMON_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); + +ErrorCode_t i2cmom_start_log(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CAP_T *pCap); + +void i2cmon_transfer_handler(ROM_I2CMON_HANDLE_T pHandle); + +uint32_t i2cmon_get_driver_version(void); + +// *** + +#endif /* __HW_I2CMOND_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..2b43e93d87706f36369425967f784143466c1b65 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.c @@ -0,0 +1,43 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 "hw_i2cmond.h" + +// This creates a table with the addresses of all the I2C functions +// This table of function pointers is the API interface. +const ROM_I2CMOND_API_T i2cmon_api = { + &i2cmon_get_mem_size, + &i2cmon_init, + &i2cmom_register_callback, + &i2cmom_start_log, + &i2cmon_transfer_handler, + &i2cmon_get_driver_version, +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..a4e126a679aff9529278e66ae587a5b4748db3ab --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2cmond_rom_api.h @@ -0,0 +1,112 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 __HW_I2CMOND_ROM_API_H +#define __HW_I2CMOND_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_i2c_common.h" + +/** @defgroup ROMAPI_I2CMON I2C monitor ROM driver functions and definitions + * @ingroup ROMAPI_I2CMON_WRAPPER + * @{ + */ + +/** @brief I2C monitor handle type */ +typedef void *ROM_I2CMON_HANDLE_T; + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a I2C monitor + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_I2CMON_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_I2CMON_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief I2C monitor optional transfer flags */ +#define ROM_I2CMON_FLAG_BLOCKING (1UL << 31) /*!< Capture function will block until complete */ +#define ROM_I2CMON_FLAG_DMARX (1UL << 29) /*!< DMA will be used for RX, requires DMA setup outside of the driver */ +#define ROM_I2CMON_FLAG_FLUSH (1UL << 25) /*!< Force monitor FIFO flush */ +#define ROM_I2CMON_FLAG_USERBITS (0xFFFF) /*!< Application can safely use the flag bits designated by this mask */ + +/** @brief Monitor transfer descriptor */ +typedef PRE_PACK struct POST_PACK { + const void *startBuff; /*!< Pointer to a buffer for capturing data after start, msy be 16-bit aligned */ + uint16_t startBuffSz; /*!< Number of bytes in startBuff buffer, data will be tossed if not big enough */ + uint16_t capStartBuffSz; /*!< Number of bytes captured in startBuff buffer */ + uint32_t flags; /*!< Optional transfer flags of type ROM_I2CMON_FLAG_* */ + volatile ErrorCode_t status; /*!< LPC_OK, busy status, or error code */ +} ROM_I2CMON_CAP_T; + +/** I2C monitor callback IDs */ +typedef enum { + ROM_I2CMON_CAPTUREREADY_CB = 0, /*!< Callback ID for I2C monitor capture ready */ + ROM_I2CMON_DMASETUP_CB /*!< Callback for DMA setup */ +} ROM_I2CMON_CALLBACK_T; + +/** @brief I2C monitor capture complete callback prototype + * The I2C monitor state machine will call this function when it captures an I2C transfer. + */ +typedef void (*i2cMonCapReadyCB)(ROM_I2CMON_HANDLE_T i2cmonHandle, ROM_I2CMON_CAP_T *pCap); + +/** @brief I2C monitor capture DMA setup callback prototype + * The I2C monitor state machine will call this function when DMA needs to be setup for + * the capture oeprations. + */ +typedef void (*i2cMonSetupDMACB)(ROM_I2CMON_HANDLE_T i2cmonHandle, ROM_I2CMON_CAP_T *pCap); + +/** @brief I2C monitor initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Base address of I2C peripheral to use */ + uint8_t stretch; /*!< 0 = disable monitor clock stretching, !0 = enable */ +} ROM_I2CMON_INIT_T; + +/** @brief I2C monitor ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of I2C monitor driver */ + ROM_I2CMON_HANDLE_T (*Init)(void *mem, const ROM_I2CMON_INIT_T *pInit); /*!< Initializes the I2C monitor driver and peripheral */ + void (*RegisterCallback)(ROM_I2CMON_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); /*!< Registers an I2C monitor callback */ + ErrorCode_t (*StartLog)(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CAP_T *pCap); /*!< Start/queue a log descriptor */ + void (*TransferHandler)(ROM_I2CMON_HANDLE_T pHandle); /*!< I2C monitor transfer (interrupt) handler */ + uint32_t (*GetDriverVersion)(void); +} ROM_I2CMOND_API_T; + +/** + * @} + */ + +extern const ROM_I2CMOND_API_T i2cmon_api; // so application program can access pointer to +// function table + +#endif /* __HW_I2CMOND_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.c new file mode 100644 index 0000000000000000000000000000000000000000..edab3a9cdfc2d22c59f272173303e53173f8fbc9 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.c @@ -0,0 +1,301 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 +#include +#include "hw_i2csd.h" + +#define DRVVERSION 0x0100 + +/* Private data structure used for the I2C slave driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_I2C_T *base; /*!< Base address of I2C peripheral to use */ + i2cSlaveStartCB pXferStartCB; /*!< Transfer start callback */ + i2cSlaveTransmitCB pTranTranCb; /*!< Data transmit callback */ + i2cSlaveReceiveCB pTranRecvCb; /*!< Data Receive callback */ + i2cSlaveCompleteCB pXferCompCB; /*!< Transfer complete callback */ + ROM_I2CS_XFER_T *pXfer; /*!< Pointer to current transfer */ + ErrorCode_t pendingStatus; /*!< Pending transfer status */ +} I2CS_DATACONTEXT_T; + +#define _rom_i2csEnable(pI2C) (pI2C->CFG |= I2C_CFG_SLVEN); +#define _rom_i2csGetSlaveAddr(pI2C, slvNum) ((pI2C->SLVADR[slvNum] >> 1) & 0x7F) +#define _rom_i2csGetSlaveMatchIndex(pI2C) ((pI2C->STAT & I2C_STAT_SLVIDX) >> 12) +#define _rom_i2csGetSlaveState(pI2C) (((pI2C->STAT & I2C_STAT_SLVSTATE) >> 9) & 0x3) + +// ********************************************************** +uint32_t i2cs_get_mem_size(void) +{ + return sizeof(I2CS_DATACONTEXT_T); +} + +ROM_I2CS_HANDLE_T i2cs_init(void *mem, const ROM_I2CS_INIT_T *pInit) +{ + I2CS_DATACONTEXT_T *pDrv; + + /* Verify alignment is at least 4 bytes */ + if (((uint32_t) mem & 0x3) != 0) { + return NULL; + } + + pDrv = (I2CS_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(I2CS_DATACONTEXT_T)); + + /* Save base of peripheral and pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_I2C_T *) pInit->base; + + /* If this needs to be changed, it should be done in the app after + this call. */ + pDrv->base->CLKDIV = 2; + + /* Clear controller state */ + pDrv->base->STAT = (I2C_STAT_SLVSEL | I2C_STAT_SLVDESEL); + + /* Enable I2C slave interface */ + _rom_i2csEnable(pDrv->base); + + return pDrv; +} + +void i2cs_setup_slave(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_SLAVE_T *pSlaveSetup) +{ + uint32_t sa, idx; + I2CS_DATACONTEXT_T *pDrv = (I2CS_DATACONTEXT_T *) pHandle; + + /* Limit usable slave address indexes to the maximum the controller can support */ + if (pSlaveSetup->SlaveIndex <= 3) { + sa = (uint32_t) (pSlaveSetup->slaveAddr & 0x7F) << 1; + if (pSlaveSetup->EnableSlave == 0) { + sa |= I2C_SLVADR_SADISABLE; /* Disable slave address */ + } + + /* Setup slave address at index */ + pDrv->base->SLVADR[pSlaveSetup->SlaveIndex] = sa; + } + + /* Check all slave indexes. If any are enabled, then enable the slave interrupts, + else disable the slave interrupts. */ + sa = 0; + for (idx = 0; ((idx <= 3) && (sa == 0)); idx++) { + if ((pDrv->base->SLVADR[idx] & I2C_SLVADR_SADISABLE) == 0) { + /* Slave is enabled */ + sa = 1; + } + } + if (sa) { + pDrv->base->INTENSET = I2C_INTENSET_SLVPENDING; + + } + else { + pDrv->base->INTENCLR = (I2C_INTENSET_SLVPENDING | I2C_INTENSET_SLVDESEL); + } +} + +void i2cs_register_callback(ROM_I2CS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB) +{ + I2CS_DATACONTEXT_T *pDrv = (I2CS_DATACONTEXT_T *) pHandle; + + if (cbIndex == ROM_I2CS_START_CB) { + pDrv->pXferStartCB = (i2cSlaveStartCB) pCB; + } + else if (cbIndex == ROM_I2CS_XFERSEND_CB) { + pDrv->pTranTranCb = (i2cSlaveTransmitCB) pCB; + } + else if (cbIndex == ROM_I2CS_XFERRECV_CB) { + pDrv->pTranRecvCb = (i2cSlaveReceiveCB) pCB; + } + else if (cbIndex == ROM_I2CS_DONE_CB) { + pDrv->pXferCompCB = (i2cSlaveCompleteCB) pCB; + } +} + +ErrorCode_t i2cs_transfer(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_XFER_T *pXfer) +{ + I2CS_DATACONTEXT_T *pDrv = (I2CS_DATACONTEXT_T *) pHandle; + + /* Is transfer NULL? */ + if (pXfer == NULL) { + return ERR_I2C_PARAM; + } + + /* Save transfer descriptor */ + pDrv->pXfer = pXfer; + pXfer->status = ERR_I2C_BUSY; + pDrv->pendingStatus = LPC_OK; + pXfer->bytesSent = 0; + pXfer->bytesRecv = 0; + + return pXfer->status; +} + +// Otime = "optimize for speed of code execution" +// ...add this pragma 1 line above the interrupt service routine function. +void i2cs_transfer_handler(ROM_I2CS_HANDLE_T pHandle) +{ + I2CS_DATACONTEXT_T *pDrv = (I2CS_DATACONTEXT_T *) pHandle; + ROM_I2CS_XFER_T *pXfer = pDrv->pXfer; + + uint32_t done = 0; + uint16_t data = 0; + + uint32_t status = pDrv->base->INTSTAT; + + /* Transfer complete? */ + if ((status & I2C_INTENSET_SLVDESEL) != 0) { + pDrv->base->INTENCLR = I2C_INTENSET_SLVDESEL; + pDrv->base->STAT = I2C_STAT_SLVDESEL; + if (pXfer) { + pXfer->status = pDrv->pendingStatus; + pDrv->pXfer = NULL; + } + if (pDrv->pXferCompCB) { + pDrv->pXferCompCB(pHandle, pXfer); + } + return; + } + else if ((status & I2C_INTENSET_SLVPENDING) != 0) { + /* Determine the current I2C slave state */ + switch (_rom_i2csGetSlaveState(pDrv->base)) { + case I2C_STAT_SLVCODE_ADDR: + /* Get slave address that needs servicing */ + data = _rom_i2csGetSlaveAddr(pDrv->base, _rom_i2csGetSlaveMatchIndex(pDrv->base)); + + /* Call address callback */ + if (pDrv->pXferStartCB) { + pDrv->pXferStartCB(pHandle, data); + + /* Update transfer descriptor */ + pXfer = pDrv->pXfer; + } + pDrv->base->INTENSET = I2C_INTENSET_SLVDESEL; + break; + + case I2C_STAT_SLVCODE_RX: + /* Receive from master */ + /* A byte has been received in thee receive FIFO */ + if ((pXfer == NULL) || (pXfer->bytesRecv >= pXfer->rxSz)) { + /* No more data, call receive data callback */ + if (pDrv->pTranRecvCb) { + done = pDrv->pTranRecvCb(pHandle, pXfer); + if (pDrv->pXfer) { + pXfer = pDrv->pXfer; + pXfer->bytesRecv = 0; + } + } + } + + /* Not using DMA */ + if (!(done == ROM_I2CS_DMA)) { + data = (uint8_t) pDrv->base->SLVDAT; + if (pXfer == NULL) { + /* Toss data and NAK, no buffer space */ + done = ROM_I2CS_NAK; + pDrv->pendingStatus = ERR_I2C_BUFFER_OVERFLOW; + } + else { + uint8_t *p8 = pXfer->rxBuff; + if ((p8 == NULL) || (pXfer->bytesRecv >= pXfer->rxSz)) { + /* Toss data and NAK, no buffer space */ + done = ROM_I2CS_NAK; + pDrv->pendingStatus = ERR_I2C_BUFFER_OVERFLOW; + } + else { + p8[pXfer->bytesRecv] = (uint8_t) data; + pDrv->pXfer->bytesRecv++; + } + } + } + break; + + case I2C_STAT_SLVCODE_TX: + /* Send to master */ + /* A byte needs to be placed into the transmit FIFO */ + if ((pXfer == NULL) || (pXfer->bytesSent >= pXfer->txSz)) { + /* Does callback exist? */ + if (pDrv->pTranTranCb) { + done = pDrv->pTranTranCb(pHandle, pXfer); + /* Can't really NAK on read, so switch to continue */ + if (pDrv->pXfer) { + pXfer = pDrv->pXfer; + pXfer->bytesSent = 0; + } + if (done == ROM_I2CS_NAK) { + pDrv->base->SLVDAT = 0; + } + } + } + + /* Continue if not DMA or NAK */ + if (!((done == ROM_I2CS_NAK) || (done == ROM_I2CS_DMA))) { + if (pXfer == NULL) { + pDrv->base->SLVDAT = 0; + pDrv->pendingStatus = ERR_I2C_BUFFER_UNDERFLOW; + done = 0; + } + else { + uint8_t *p8 = (uint8_t *) pXfer->txBuff; + /* Not using DMA, so this is a normal transfer */ + if ((p8 == NULL) || (pXfer->bytesSent >= pXfer->txSz)) { + /* Have to send something, so NAK with 0 */ + pDrv->base->SLVDAT = 0; + pDrv->pendingStatus = ERR_I2C_BUFFER_UNDERFLOW; + done = 0; + } + else { + pDrv->base->SLVDAT = (uint32_t) p8[pXfer->bytesSent]; + pDrv->pXfer->bytesSent++; + } + } + } + break; + } + + if (done == ROM_I2CS_NAK) { + pDrv->base->SLVCTL = I2C_SLVCTL_SLVNACK; + } + else if (done == ROM_I2CS_DMA) { + pDrv->base->SLVCTL = I2C_SLVCTL_SLVDMA; + } + else { + pDrv->base->SLVCTL = I2C_SLVCTL_SLVCONTINUE; + } + } +} + +uint32_t i2cs_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.h new file mode 100644 index 0000000000000000000000000000000000000000..d599b8b06d74306cc8f5ac0634ed1bc1be9a201b --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd.h @@ -0,0 +1,55 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 __HW_I2CSD_H +#define __HW_I2CSD_H + +#include "error.h" +#include "hw_i2csd_rom_api.h" + +// *** I2C functions called by Application Program *** +uint32_t i2cs_get_mem_size(void); + +ROM_I2CS_HANDLE_T i2cs_init(void *mem, const ROM_I2CS_INIT_T *pInit); + +void i2cs_setup_slave(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_SLAVE_T *pSlaveSetup); + +void i2cs_register_callback(ROM_I2CS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); + +ErrorCode_t i2cs_transfer(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_XFER_T *pXfer); + +void i2cs_transfer_handler(ROM_I2CS_HANDLE_T pHandle); + +uint32_t i2cs_get_driver_version(void); + +// *** + +#endif /* __HW_I2CSD_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..b2c9dbd0494ce71499756b62bb68bf25e1daa5c8 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.c @@ -0,0 +1,44 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 "hw_i2csd.h" + +// This creates a table with the addresses of all the I2C functions +// This table of function pointers is the API interface. +const ROM_I2CSD_API_T i2cs_api = { + &i2cs_get_mem_size, + &i2cs_init, + &i2cs_setup_slave, + &i2cs_register_callback, + &i2cs_transfer, + &i2cs_transfer_handler, + &i2cs_get_driver_version, +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..e5eba2c9fd0b61337371722d7d475b2036494740 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_i2csd_rom_api.h @@ -0,0 +1,151 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 __HW_I2CSD_ROM_API_H +#define __HW_I2CSD_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_i2c_common.h" + +/** @defgroup ROMAPI_I2CS I2C slave ROM driver functions and definitions + * @ingroup ROMAPI_I2CS_WRAPPER + * @{ + */ + +/** @brief I2C slave handle type */ +typedef void *ROM_I2CS_HANDLE_T; + +/** @brief Maximum number of slave addresses supported by this driver */ +#define ROM_I2CS_MAX_SLAVES 4 + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a I2C master + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_I2CS_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_I2CS_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief I2C master optional transfer flags */ +#define ROM_I2CS_FLAG_USERBITS (0xFFFF) /*!< Application can safely use the flag bits designated by this mask */ + +/** @brief slave transfer descriptor */ +typedef PRE_PACK struct POST_PACK { + const void *txBuff; /*!< Pointer to array of bytes to be transmitted */ + void *rxBuff; /*!< Pointer memory where bytes received from I2C be stored */ + volatile ErrorCode_t status; /*!< Packed status of the current I2C transfer (ErrorCode_t), must be 32-bits */ + uint32_t flags; /*!< Reserved, set to 0 */ + uint16_t txSz; /*!< Number of bytes in transmit array, if 0 only receive transfer will be performed */ + uint16_t rxSz; /*!< Number of bytes to receive, if 0 only transmission will be performed */ + uint16_t bytesSent; /*!< Number of bytes sent */ + uint16_t bytesRecv; /*!< Number of bytes recevied */ +} ROM_I2CS_XFER_T; + +/** I2C slave callback IDs */ +typedef enum { + ROM_I2CS_START_CB = 0, /*!< Callback ID for I2C slave service start callback */ + ROM_I2CS_XFERSEND_CB, /*!< Callback ID for I2C slave send data callback */ + ROM_I2CS_XFERRECV_CB, /*!< Callback ID for I2C slave receive data callback */ + ROM_I2CS_DONE_CB, /*!< Callback ID for I2C slave service done callback */ +} ROM_I2CS_CALLBACK_T; + +/** @brief I2C slave state machine transfer control */ +typedef enum { + ROM_I2CS_CONTINUE = 0, /*!< Continue transfer */ + ROM_I2CS_NAK, /*!< Will NAK master at next opportunity */ + ROM_I2CS_DMA /*!< Tell I2C handler DMA is handling the data */ +} ROM_I2CS_TRANCTRL_T; + +/** @brief I2C slave transfer start callback + * This callback is called from the I2C slave handler when an I2C slave address supported + * by the controller is addressed. + */ +typedef void (*i2cSlaveStartCB)(ROM_I2CS_HANDLE_T i2csHandle, uint16_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 in the transfer descriptor. It is called on demand only when transmit + * data is needed for the transmit FIFO and the descriptor buffer is empty.
+ * If you want to NAK the master, return ROM_I2CS_NAK to the caller. + * Return ROM_I2CS_CONTINUE or 0 to the caller for normal non-DMA data transfer. + * If you've setup a DMA descriptor for the transfer, return ROM_I2CS_DMA to the caller.
+ */ +typedef ROM_I2CS_TRANCTRL_T (*i2cSlaveTransmitCB)(ROM_I2CS_HANDLE_T i2csHandle, ROM_I2CS_XFER_T *pXfer); + +/** @brief I2C slave receive data callback + * This callback is called from the I2C slave handler when an I2C slave address has + * receive data and the receive buffer is full.
+ * If you want to NAK the master, return ROM_I2CS_NAK to the caller. + * Return ROM_I2CS_CONTINUE or 0 to the caller for normal non-DMA data transfer. + * If you've setup a DMA descriptor for the transfer, return ROM_I2CS_DMA to the caller.
+ */ +typedef ROM_I2CS_TRANCTRL_T (*i2cSlaveReceiveCB)(ROM_I2CS_HANDLE_T i2csHandle, ROM_I2CS_XFER_T *pXfer); + +/** @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 (*i2cSlaveCompleteCB)(ROM_I2CS_HANDLE_T i2csHandle, ROM_I2CS_XFER_T *pXfer); + +/** @brief I2C slave initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Base address of I2C peripheral to use */ +} ROM_I2CS_INIT_T; + +/** @brief I2C slave address setup structure */ +typedef PRE_PACK struct POST_PACK { + uint16_t slaveAddr; /*!< Slave address used for this index in the controller */ + uint8_t SlaveIndex; /*!< Slave index to use, 0 is first index */ + uint8_t EnableSlave; /*!< Set to 0 to disable this slave index, or non-0 to enable */ +} ROM_I2CS_SLAVE_T; + +/** @brief I2C slave ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of I2C slave driver */ + ROM_I2CS_HANDLE_T (*Init)(void *mem, const ROM_I2CS_INIT_T *pInit); /*!< Initializes the I2C slave driver and peripheral */ + void (*SetupSlave)(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_SLAVE_T *pSlaveSetup); /*!< Sets up a slave address to use with the I2C controller */ + void (*RegisterCallback)(ROM_I2CS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); /*!< Registers an I2C slave callback */ + ErrorCode_t (*Transfer)(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_XFER_T *pXfer); /*!< Queues an I2C slave transfer */ + void (*TransferHandler)(ROM_I2CS_HANDLE_T pHandle); /*!< I2C slave transfer (interrupt) handler */ + uint32_t (*GetDriverVersion)(void); +} ROM_I2CSD_API_T; + +/** + * @} + */ + +extern const ROM_I2CSD_API_T i2cs_api; // so application program can access pointer to +// function table + +#endif /* __HW_I2CSD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spi_common.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spi_common.h new file mode 100644 index 0000000000000000000000000000000000000000..6c0088786cddf530e2c013f191a395e2dd277b35 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spi_common.h @@ -0,0 +1,187 @@ +/* + * @brief SPI ROM API declarations and functions + * + * @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 __HW_SPI_COMMON_H_ +#define __HW_SPI_COMMON_H_ + +/** + * @brief SPI register block structure + */ +typedef struct { /*!< SPI Structure */ + volatile uint32_t CFG; /*!< SPI Configuration register */ + volatile uint32_t DLY; /*!< SPI Delay register */ + volatile uint32_t STAT; /*!< SPI Status register */ + volatile uint32_t INTENSET; /*!< SPI Interrupt Enable Set register */ + volatile uint32_t INTENCLR; /*!< SPI Interrupt Enable Clear register */ + volatile uint32_t RXDAT; /*!< SPI Receive Data register */ + volatile uint32_t TXDATCTL; /*!< SPI Transmit Data with Control register */ + volatile uint32_t TXDAT; /*!< SPI Transmit Data register */ + volatile uint32_t TXCTRL; /*!< SPI Transmit Control register */ + volatile uint32_t DIV; /*!< SPI clock Divider register */ + volatile uint32_t INTSTAT; /*!< SPI Interrupt Status register */ +} LPC_SPI_T; + +/** + * Macro defines for SPI Configuration register + */ +#define SPI_CFG_BITMASK (0xFBD) /** SPI register bit mask */ +#define SPI_CFG_SPI_EN (1 << 0) /** SPI Slave Mode Select */ +#define SPI_CFG_SLAVE_EN (0 << 0) /** SPI Master Mode Select */ +#define SPI_CFG_MASTER_EN (1 << 2) /** SPI MSB First mode enable */ +#define SPI_CFG_MSB_FIRST_EN (0 << 3) /** SPI LSB First mode enable */ +#define SPI_CFG_LSB_FIRST_EN (1 << 3) /** SPI Clock Phase Select */ +#define SPI_CFG_CPHA_FIRST (0 << 4) /** Capture data on the first edge, Change data on the following edge */ +#define SPI_CFG_CPHA_SECOND (1 << 4) /** SPI Clock Polarity Select */ +#define SPI_CFG_CPOL_LO (0 << 5) /** The rest state of the clock (between frames) is low. */ +#define SPI_CFG_CPOL_HI (1 << 5) /** The rest state of the clock (between frames) is high. */ +#define SPI_CFG_LBM_EN (1 << 7) /** SPI control 1 loopback mode enable */ +#define SPI_CFG_SPOL_LO (0 << 8) /** SPI SSEL0 Polarity Select */ +#define SPI_CFG_SPOL_HI (1 << 8) /** SSEL0 is active High */ +#define SPI_CFG_SPOLNUM_HI(n) (1 << ((n) + 8)) /** SSELN is active High, selects 0 - 3 */ + +/** + * Macro defines for SPI Delay register + */ +#define SPI_DLY_BITMASK (0xFFFF) /** SPI DLY Register Mask */ +#define SPI_DLY_PRE_DELAY(n) (((n) & 0x0F) << 0) /** Time in SPI clocks between SSEL assertion and the beginning of a data frame */ +#define SPI_DLY_POST_DELAY(n) (((n) & 0x0F) << 4) /** Time in SPI clocks between the end of a data frame and SSEL deassertion. */ +#define SPI_DLY_FRAME_DELAY(n) (((n) & 0x0F) << 8) /** Minimum time in SPI clocks between adjacent data frames. */ +#define SPI_DLY_TRANSFER_DELAY(n) (((n) & 0x0F) << 12) /** Minimum time in SPI clocks that the SSEL is deasserted between transfers. */ + +/** + * Macro defines for SPI Status register + */ +#define SPI_STAT_BITMASK (0x1FF) /** SPI STAT Register BitMask */ +#define SPI_STAT_RXRDY (1 << 0) /** Receiver Ready Flag */ +#define SPI_STAT_TXRDY (1 << 1) /** Transmitter Ready Flag */ +#define SPI_STAT_RXOV (1 << 2) /** Receiver Overrun interrupt flag */ +#define SPI_STAT_TXUR (1 << 3) /** Transmitter Underrun interrupt flag (In Slave Mode only) */ +#define SPI_STAT_SSA (1 << 4) /** Slave Select Assert */ +#define SPI_STAT_SSD (1 << 5) /** Slave Select Deassert */ +#define SPI_STAT_STALLED (1 << 6) /** Stalled status flag */ +#define SPI_STAT_EOT (1 << 7) /** End Transfer flag */ +#define SPI_STAT_MSTIDLE (1 << 8) /** Idle status flag */ + +/** + * Macro defines for SPI Interrupt Enable read and Set register + */ +#define SPI_INTENSET_BITMASK (0x3F) /** SPI INTENSET Register BitMask */ +#define SPI_INTENSET_RXDYEN (1 << 0) /** Enable Interrupt when receiver data is available */ +#define SPI_INTENSET_TXDYEN (1 << 1) /** Enable Interrupt when the transmitter holding register is available. */ +#define SPI_INTENSET_RXOVEN (1 << 2) /** Enable Interrupt when a receiver overrun occurs */ +#define SPI_INTENSET_TXUREN (1 << 3) /** Enable Interrupt when a transmitter underrun occurs (In Slave Mode Only)*/ +#define SPI_INTENSET_SSAEN (1 << 4) /** Enable Interrupt when the Slave Select is asserted.*/ +#define SPI_INTENSET_SSDEN (1 << 5) /** Enable Interrupt when the Slave Select is deasserted..*/ + +/** + * Macro defines for SPI Interrupt Enable Clear register + */ +#define SPI_INTENCLR_BITMASK (0x3F) /** SPI INTENCLR Register BitMask */ +#define SPI_INTENCLR_RXDYEN (1 << 0) /** Disable Interrupt when receiver data is available */ +#define SPI_INTENCLR_TXDYEN (1 << 1) /** Disable Interrupt when the transmitter holding register is available. */ +#define SPI_INTENCLR_RXOVEN (1 << 2) /** Disable Interrupt when a receiver overrun occurs */ +#define SPI_INTENCLR_TXUREN (1 << 3) /** Disable Interrupt when a transmitter underrun occurs (In Slave Mode Only) */ +#define SPI_INTENCLR_SSAEN (1 << 4) /** Disable Interrupt when the Slave Select is asserted. */ +#define SPI_INTENCLR_SSDEN (1 << 5) /** Disable Interrupt when the Slave Select is deasserted.. */ + +/** + * Macro defines for SPI Receiver Data register + */ +#define SPI_RXDAT_BITMASK (0x1FFFFF) /** SPI RXDAT Register BitMask */ +#define SPI_RXDAT_DATA(n) ((n) & 0xFFFF) /** Receiver Data */ +#define SPI_RXDAT_RXSSELN_ACTIVE (0 << 16) /** The state of SSEL pin is active */ +#define SPI_RXDAT_RXSSELN_INACTIVE ((1 << 16) /** The state of SSEL pin is inactive */ +#define SPI_RXDAT_RXSSELNUM_INACTIVE(n) (1 << ((n) + 16)) /** The state of SSELN pin is inactive */ +#define SPI_RXDAT_SOT (1 << 20) /** Start of Transfer flag */ + +/** + * Macro defines for SPI Transmitter Data and Control register + */ +#define SPI_TXDATCTL_BITMASK (0xF7FFFFF) /** SPI TXDATCTL Register BitMask */ +#define SPI_TXDATCTL_DATA(n) ((n) & 0xFFFF) /** SPI Transmit Data */ +#define SPI_TXDATCTL_CTRLMASK (0xF7F0000) /** SPI TXDATCTL Register BitMask for control bits only */ +#define SPI_TXDATCTL_ASSERT_SSEL (0 << 16) /** Assert SSEL0 pin */ +#define SPI_TXDATCTL_DEASSERT_SSEL (1 << 16) /** Deassert SSEL0 pin */ +#define SPI_TXDATCTL_DEASSERTNUM_SSEL(n) (1 << ((n) + 16)) /** Deassert SSELN pin */ +#define SPI_TXDATCTL_DEASSERT_ALL (0xF << 16) /** Deassert all SSEL pins */ +#define SPI_TXDATCTL_EOT (1 << 20) /** End of Transfer flag (TRANSFER_DELAY is applied after sending the current frame) */ +#define SPI_TXDATCTL_EOF (1 << 21) /** End of Frame flag (FRAME_DELAY is applied after sending the current part) */ +#define SPI_TXDATCTL_RXIGNORE (1 << 22) /** Receive Ignore Flag */ +#define SPI_TXDATCTL_FLEN(n) (((n) & 0x0F) << 24) /** Frame length - 1 */ + +/** + * Macro defines for SPI Transmitter Data Register + */ +#define SPI_TXDAT_DATA(n) ((n) & 0xFFFF) /** SPI Transmit Data */ + +/** + * Macro defines for SPI Transmitter Control register + */ +#define SPI_TXCTL_BITMASK (0xF7F0000) /** SPI TXDATCTL Register BitMask */ +#define SPI_TXCTL_ASSERT_SSEL (0 << 16) /** Assert SSEL0 pin */ +#define SPI_TXCTL_DEASSERT_SSEL (1 << 16) /** Deassert SSEL0 pin */ +#define SPI_TXCTL_DEASSERTNUM_SSEL(n) (1 << ((n) + 16)) /** Deassert SSELN pin */ +#define SPI_TXDATCTL_DEASSERT_ALL (0xF << 16) /** Deassert all SSEL pins */ +#define SPI_TXCTL_EOT (1 << 20) /** End of Transfer flag (TRANSFER_DELAY is applied after sending the current frame) */ +#define SPI_TXCTL_EOF (1 << 21) /** End of Frame flag (FRAME_DELAY is applied after sending the current part) */ +#define SPI_TXCTL_RXIGNORE (1 << 22) /** Receive Ignore Flag */ +#define SPI_TXCTL_FLEN(n) ((((n) - 1) & 0x0F) << 24) /** Frame length, 0 - 16 */ +#define SPI_TXCTL_FLENMASK (0xF << 24) /** Frame length mask */ + +/** + * Macro defines for SPI Divider register + */ +#define SPI_DIV_VAL(n) ((n) & 0xFFFF) /** Rate divider value mask (In Master Mode only)*/ + +/** + * Macro defines for SPI Interrupt Status register + */ +#define SPI_INTSTAT_BITMASK (0x3F) /** SPI INTSTAT Register Bitmask */ +#define SPI_INTSTAT_RXRDY (1 << 0) /** Receiver Ready Flag */ +#define SPI_INTSTAT_TXRDY (1 << 1) /** Transmitter Ready Flag */ +#define SPI_INTSTAT_RXOV (1 << 2) /** Receiver Overrun interrupt flag */ +#define SPI_INTSTAT_TXUR (1 << 3) /** Transmitter Underrun interrupt flag (In Slave Mode only) */ +#define SPI_INTSTAT_SSA (1 << 4) /** Slave Select Assert */ +#define SPI_INTSTAT_SSD (1 << 5) /** Slave Select Deassert */ + +/** @brief SPI Clock Mode*/ +typedef enum { + ROM_SPI_CLOCK_CPHA0_CPOL0 = 0, /**< CPHA = 0, CPOL = 0 */ + ROM_SPI_CLOCK_MODE0 = ROM_SPI_CLOCK_CPHA0_CPOL0, /**< Alias for CPHA = 0, CPOL = 0 */ + ROM_SPI_CLOCK_CPHA1_CPOL0 = 1, /**< CPHA = 0, CPOL = 1 */ + ROM_SPI_CLOCK_MODE1 = ROM_SPI_CLOCK_CPHA1_CPOL0, /**< Alias for CPHA = 0, CPOL = 1 */ + ROM_SPI_CLOCK_CPHA0_CPOL1 = 2, /**< CPHA = 1, CPOL = 0 */ + ROM_SPI_CLOCK_MODE2 = ROM_SPI_CLOCK_CPHA0_CPOL1, /**< Alias for CPHA = 1, CPOL = 0 */ + ROM_SPI_CLOCK_CPHA1_CPOL1 = 3, /**< CPHA = 1, CPOL = 1 */ + ROM_SPI_CLOCK_MODE3 = ROM_SPI_CLOCK_CPHA1_CPOL1, /**< Alias for CPHA = 1, CPOL = 1 */ +} ROM_SPI_CLOCK_MODE_T; + +#endif /* __HW_SPI_COMMON_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.c new file mode 100644 index 0000000000000000000000000000000000000000..bd6ae6fd762f118ef6eeb339a25198101b2c36e3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.c @@ -0,0 +1,581 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 +#include +#include "hw_spimd.h" + +#define DRVVERSION 0x0100 + +/* Private callback for FIFO push and pop functions. This privately maps + to the VFIFO for the SPI master, but can be overriden if needed. The driver will + automatically pick the right implementation at run-time based on the transfer + size in the transfer descriptor. */ +typedef uint16_t (*spiMasterFifoPushFN)(LPC_SPI_T *pSPI, void *data, uint32_t sendBytes, uint32_t curIndex); +typedef uint16_t (*spiMasterFifoPopFN)(LPC_SPI_T *pSPI, void *data, uint32_t bytes, uint32_t curIndex); + +/* Private data structure used for the SPI master driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_SPI_T *base; /*!< Base address of SPI peripheral to use */ + uint32_t baseClockRate; /*!< SPI base clock rate in Hz, call Init() again if this rate changes */ + spiMasterXferCSAssertCB pAssertCb; /*!< SSEL assertion callback */ + spiMasterTransmitCB pTranCb; /*!< Transmit data start callback */ + spiMasterReceiveCB pRecvCb; /*!< Receive data start callback */ + spiMMasterXferCSDeAssertCB pDeassertCb; /*!< SSEL deassertion callback */ + spiMasterFifoPushFN pPushFN; /*!< Pointer to current FIFO push function */ + spiMasterFifoPopFN pPopFN; /*!< Pointer to current FIFO pop function */ + ROM_SPIM_XFER_T *pXfer; /*!< Pointer to current transfer descriptor */ + uint32_t sendIdx; /*!< Current transmit buffer index */ + uint32_t recvIdx; /*!< Current receive buffer index */ + ErrorCode_t pendingStatus; /*!< Pending transfer status */ + uint8_t xmitOn; /*!< Transfer in progress flag */ + uint8_t terminate; /*!< Terminate transfer flag */ + uint8_t reserved[2]; +} SPIM_DATACONTEXT_T; + +/* Maps config registers bits for SPI mode to the transfer descriptor */ +static const uint32_t spiModeBits[4] = { + (SPI_CFG_CPOL_LO | SPI_CFG_CPHA_FIRST), + (SPI_CFG_CPOL_LO | SPI_CFG_CPHA_SECOND), + (SPI_CFG_CPOL_HI | SPI_CFG_CPHA_FIRST), + (SPI_CFG_CPOL_HI | SPI_CFG_CPHA_SECOND) +}; + +void spim_close_pending_transfer(ROM_SPIM_HANDLE_T pHandle); + +/* FIFO push function using standard SPI FIFO for datum >8 bits */ +static uint16_t _rom_spimMasterFifoPush16(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t pushed = 0, *p16 = (uint16_t *) data; + + /* Push as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_TXRDY) != 0)) { + pSPI->TXDAT = (uint32_t) p16[curIndex]; + numData--; + curIndex++; + pushed++; + } + + return pushed; +} + +/* FIFO pop function using standard SPI FIFO for datum >8 bits */ +static uint16_t _rom_spimMasterFifoPop16(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t popped = 0, *p16 = (uint16_t *) data; + + /* Pop as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_RXRDY) != 0)) { + p16[curIndex] = (uint16_t) pSPI->RXDAT; + numData--; + curIndex++; + popped++; + } + + return popped; +} + +/* FIFO push function using standard SPI FIFO for datum <=8 bits */ +static uint16_t _rom_spimMasterFifoPush8(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t pushed = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Push as 8-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_TXRDY) != 0)) { + pSPI->TXDAT = (uint32_t) p8[curIndex]; + numData--; + curIndex++; + pushed++; + } + + return pushed; +} + +/* FIFO pop function using standard SPI FIFO for datum <=8 bits */ +static uint16_t _rom_spimMasterFifoPop8(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t popped = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Pop as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_RXRDY) != 0)) { + p8[curIndex] = (uint8_t) pSPI->RXDAT; + numData--; + curIndex++; + popped++; + } + + return popped; +} + +/* Assert a SPI select */ +static void _rom_spimAssertSSEL(LPC_SPI_T *pSPI, uint8_t sselNum) +{ + /* Assert a SSEL line by driving it low */ + pSPI->TXCTRL &= ~SPI_TXDATCTL_DEASSERTNUM_SSEL(sselNum); +} + +static void _rom_spimCloseTransfer(SPIM_DATACONTEXT_T *pDrv) +{ + /* Transfer terminates after this byte */ + pDrv->xmitOn = 0; + pDrv->base->INTENCLR = SPI_INTENSET_TXDYEN; +} + +static void _rom_spimTransmitHandler(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIM_FLAG_DMATX) != 0) { + /* Call transmit callback, callback is pre-validated by setup */ + if (pDrv->pTranCb) { + pDrv->pTranCb(pHandle, pXfer); + + pDrv->base->INTENCLR = SPI_INTENSET_TXDYEN; + } + } + else { /* Transfer without using DMA */ + if ((pXfer->flags & ROM_SPIM_FLAG_TXIGNORE) != 0) { + /* ROM_SPIM_FLAG_TXIGNORE flag is set. Will send 0xFF and decrement txSz, + transfer terminates on last data */ + static const uint16_t sb = 0xFFFF; + if (pDrv->sendIdx >= pXfer->txSz) { + /* Transferring last datum, end transfer */ + spim_close_pending_transfer(pHandle); + } + else { + if (pDrv->sendIdx >= (pXfer->txSz - 1)) { + pDrv->base->TXCTRL |= SPI_TXCTL_EOT; + } + pDrv->sendIdx += pDrv->pPushFN(pDrv->base, (void *) &sb, 1, 0); + } + } + else { + /* Normal data transfer */ + if (pDrv->sendIdx >= pXfer->txSz) { + /* Ran out of data, so stop */ + spim_close_pending_transfer(pHandle); + } + else { + pDrv->sendIdx += pDrv->pPushFN(pDrv->base, (void *) pXfer->txBuff, 1, pDrv->sendIdx); + + /* Call callback for more data */ + if (pDrv->sendIdx >= pXfer->txSz) { + if (pDrv->pTranCb) { + pDrv->pTranCb(pHandle, pXfer); + pDrv->sendIdx = 0; + } + else { + /* No transmit callback, close transfer */ + spim_close_pending_transfer(pHandle); + } + } + } + } + } +} + +static void _rom_spimReceiveHandler(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIM_FLAG_DMARX) != 0) { + /* Call receive callback, callback is pre-validated by setup */ + if (pDrv->pRecvCb) { + pDrv->pRecvCb(pHandle, pXfer); + + pDrv->base->INTENCLR = SPI_INTENSET_RXDYEN; + } + } + else { /* Transfer without using DMA */ + /* Normal data transfer */ + if (pDrv->recvIdx >= pXfer->rxSz) { + uint16_t temp; + /* Ran out of data, overflowing */ + pDrv->pendingStatus = ERR_SPI_RXOVERRUN; + pDrv->recvIdx += pDrv->pPopFN(pDrv->base, (void *) &temp, 1, 0); /* Flush data */ + } + else { + pDrv->recvIdx += pDrv->pPopFN(pDrv->base, (void *) pXfer->rxBuff, 1, pDrv->recvIdx); + + /* Call callback for more data */ + if ((pDrv->recvIdx >= pXfer->rxSz) && (pDrv->pRecvCb)) { + pDrv->pRecvCb(pHandle, pXfer); + pDrv->recvIdx = 0; + } + } + } +} + +// ********************************************************** +uint32_t spim_get_mem_size(void) +{ + return sizeof(SPIM_DATACONTEXT_T); +} + +ROM_SPIM_HANDLE_T spim_init(void *mem, const ROM_SPIM_INIT_T *pInit) +{ + SPIM_DATACONTEXT_T *pDrv; + int i; + + /* Verify alignment is at least 4 bytes and clock rate is not 0 */ + if ((((uint32_t) mem & 0x3) != 0) || (pInit->baseClockRate == 0)) { + return NULL; + } + + pDrv = (SPIM_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(SPIM_DATACONTEXT_T)); + + /* Save base of peripheral and pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_SPI_T *) pInit->base; + pDrv->baseClockRate = pInit->baseClockRate; + + /* Enable SPI master interface, deassert all chip selects */ + pDrv->base->CFG = 0;/* Forces state machine reset */ + pDrv->base->CFG = SPI_CFG_SPI_EN | SPI_CFG_MASTER_EN; + + /* Set SPI slave select (SSEL) polarity for each slave signal */ + for (i = 0; i <= 3; i++) { + if (pInit->spiPol[i] == 0) { + /* Active low select, high during idle */ + pDrv->base->CFG &= ~(1 << (8 + i)); + } + else { + /* Active high, low during idle */ + pDrv->base->CFG |= (1 << (8 + i)); + } + } + + /* Deassert all chip selects */ + pDrv->base->TXCTRL = SPI_TXDATCTL_DEASSERT_ALL; + + /* Clear pending master statuses - RXOV, TXUR, SSA, SSD, EOT */ + pDrv->base->STAT = (SPI_STAT_RXOV | SPI_STAT_TXUR | SPI_STAT_SSA | + SPI_STAT_SSD | SPI_STAT_EOT); + + return (ROM_SPIM_HANDLE_T) pDrv; +} + +void spim_register_callback(ROM_SPIM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + + switch (cbIndex) { + case ROM_SPIM_ASSERTSSEL_CB: + pDrv->pAssertCb = (spiMasterXferCSAssertCB) pCB; + break; + + case ROM_SPIM_DATATRANSMIT_CB: + pDrv->pTranCb = (spiMasterTransmitCB) pCB; + break; + + case ROM_SPIM_DATATRECEIVE_CB: + pDrv->pRecvCb = (spiMasterReceiveCB) pCB; + break; + + case ROM_SPIM_DEASSERTSSEL_CB: + pDrv->pDeassertCb = (spiMMasterXferCSDeAssertCB) pCB; + break; + } +} + +ErrorCode_t spim_setup_transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_CONFIG_T *pCfg) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + uint32_t reg; + + /* Verify config is valid */ + if (pCfg == NULL) { + return ERR_SPI_PARAM; + } + + /* Verify data parameters area valid */ + if ((pCfg->dataBits == 0) || (pCfg->dataBits > 16) || (pCfg->dXferBitRate == 0)) { + return ERR_SPI_PARAM; + } + + /* Verify mode */ + if (pCfg->mode > ROM_SPI_CLOCK_MODE3) { + return ERR_SPI_PARAM; + } + + /* Transfer timing is valid? */ + if ((pCfg->PreDelay > 15) || (pCfg->PostDelay > 15) || (pCfg->FrameDelay > 15) || + (pCfg->TransferDelay > 16)) { + return ERR_SPI_PARAM; + } + + /* Compute real clock rate from desired clock rate */ + reg = pDrv->baseClockRate / pCfg->dXferBitRate; + if ((pDrv->baseClockRate % pCfg->dXferBitRate) != 0) { + reg++; + } + if (reg > 0x10000) { + reg = 0x10000; + } + else if (reg == 0) { + reg = 1; + } + + /* Save pre-computed divider and set real SPI master bit rate for app */ + pDrv->base->DIV = (reg - 1); + pCfg->rXferBitRate = pDrv->baseClockRate / reg; + + /* Setup transfer timing */ + if (pCfg->TransferDelay == 0) { + pCfg->TransferDelay = 1; + } + pDrv->base->DLY = ( + SPI_DLY_PRE_DELAY(pCfg->PreDelay) | + SPI_DLY_POST_DELAY(pCfg->PostDelay) | + SPI_DLY_FRAME_DELAY(pCfg->FrameDelay) | + SPI_DLY_TRANSFER_DELAY(pCfg->TransferDelay - 1)); + + /* Setup transfer mode and LSB/MSB first */ + reg = pDrv->base->CFG; + reg &= ~(SPI_CFG_LSB_FIRST_EN | SPI_CFG_CPHA_SECOND | + SPI_CFG_CPOL_HI); + + /* Setup SPI transfer configuration (CFG register) */ + reg |= spiModeBits[(int) pCfg->mode]; + if (pCfg->lsbFirst) { + reg |= SPI_CFG_LSB_FIRST_EN; + } + pDrv->base->CFG = reg; + + /* Setup SPI transfer configuration (TXCTRL) for data size, don't alter SPI SSEL states */ + reg = pDrv->base->TXCTRL & ~SPI_TXCTL_FLEN(16); + if (pCfg->FrameDelay > 0) { + reg |= SPI_TXCTL_EOF; + } + pDrv->base->TXCTRL = reg | SPI_TXCTL_FLEN(pCfg->dataBits); + + /* Setup FIFO callbacks based on the data transfer width */ + if (pCfg->dataBits > 8) { + pDrv->pPushFN = &_rom_spimMasterFifoPush16; + pDrv->pPopFN = &_rom_spimMasterFifoPop16; + } + else { + pDrv->pPushFN = &_rom_spimMasterFifoPush8; + pDrv->pPopFN = &_rom_spimMasterFifoPop8; + } + + return LPC_OK; +} + +ErrorCode_t spim_transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + uint32_t reg; + uint8_t flen; + + /* Get length of a receive value */ + flen = 1 + (uint8_t) ((pDrv->base->TXCTRL >> 24) & 0xF); + + /* Is transfer descriptor valid? */ + if (pXfer == NULL) { + return ERR_SPI_PARAM; + } + + /* Is slave select valid? */ + if (pXfer->sselNum >= ROM_SPIM_MAXSELECTS) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + + /* Verify transmit size, must have at least 1 byte */ + if (pXfer->txSz == 0) { + pXfer->status = ERR_SPI_INVALID_LENGTH; + return ERR_SPI_INVALID_LENGTH; + } + + /* No need to check RX buffer alignment if ROM_SPIM_FLAG_RXIGNORE flag is set */ + if ((pXfer->flags & ROM_SPIM_FLAG_RXIGNORE) == 0) { + if ((pXfer->rxSz == 0) || (pXfer->rxBuff == NULL)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + if ((flen > 8) && ((((uint32_t) pXfer->rxBuff) & 0x1) != 0)) { + /* Receive buffer not 16-bit aligned or not present */ + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIM_FLAG_DMARX) != 0) { + if (pDrv->pRecvCb == NULL) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + } + } + + /* Check transmit buffer alignment */ + if ((pXfer->flags & ROM_SPIM_FLAG_TXIGNORE) == 0) { + if ((pXfer->txSz == 0) || (pXfer->txBuff == NULL)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + if ((flen > 8) && ((((uint32_t) pXfer->txBuff) & 0x1) != 0)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIM_FLAG_DMATX) != 0) { + if (pDrv->pTranCb == NULL) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + } + } + + /* If in loopback mode, set loopback enable */ + reg = pDrv->base->CFG; + if ((pXfer->flags & ROM_SPIM_FLAG_LOOPBACK) != 0) { + reg |= SPI_CFG_LBM_EN; + } + else { + reg &= ~SPI_CFG_LBM_EN; + } + pDrv->base->CFG = reg; + + /* ROM_SPIM_FLAG_RXIGNORE flag */ + reg = pDrv->base->TXCTRL & ~SPI_TXCTL_EOT; + if ((pXfer->flags & ROM_SPIM_FLAG_RXIGNORE) != 0) { + reg |= SPI_TXCTL_RXIGNORE; + } + else { + reg &= ~SPI_TXCTL_RXIGNORE; + } + pDrv->base->TXCTRL = reg; + + /* Save pointer to transfer descriptor and initial status */ + pDrv->pXfer = pXfer; + pXfer->status = ERR_SPI_BUSY; + pDrv->pendingStatus = LPC_OK; + pDrv->sendIdx = pDrv->recvIdx = 0; + + /* Transmit start, no terminate */ + pDrv->xmitOn = 1; + pDrv->terminate = 0; + + /* Start transfer by asserting selected slave */ + _rom_spimAssertSSEL(pDrv->base, pXfer->sselNum); + + /* Enable SPI interrupts for master */ + pDrv->base->INTENSET = SPI_INTENSET_RXDYEN | SPI_INTENSET_TXDYEN | + SPI_INTENSET_SSAEN | SPI_INTENSET_SSDEN; + + /* Is transfer blocking? */ + if ((pXfer->flags & ROM_SPIM_FLAG_BLOCKING) != 0) { + while (pXfer->status == ERR_SPI_BUSY) { + spim_transfer_handler(pHandle); + } + } + + return pXfer->status; +} + +// Otime = "optimize for speed of code execution" +// ...add this pragma 1 line above the interrupt service routine function. +void spim_transfer_handler(ROM_SPIM_HANDLE_T pHandle) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + ROM_SPIM_XFER_T *pXfer = pDrv->pXfer; + uint32_t status = pDrv->base->STAT; + + /* Master asserts slave */ + if ((status & SPI_STAT_SSA) != 0) { + pDrv->base->STAT = SPI_STAT_SSA; + pDrv->base->INTENCLR = SPI_INTENSET_SSAEN; + + /* Master SSEL assertion callback */ + if (pDrv->pAssertCb != NULL) { + pDrv->pAssertCb(pHandle, pXfer); + } + } + + /* Transmit data handler */ + if (((status & SPI_STAT_TXRDY) != 0) && (pDrv->xmitOn == 1)) { + /* Handle transmit */ + _rom_spimTransmitHandler(pHandle, pXfer); + } + + /* Receive data handler */ + if ((status & SPI_STAT_RXRDY) != 0) { + /* Handle receive */ + _rom_spimReceiveHandler(pHandle, pXfer); + } + + /* If the controller is stalled and the transmit is finished, close the transfer + or be stuck in a stalled condition indefinitely. */ + if (((status & SPI_STAT_STALLED) != 0) && (pDrv->xmitOn == 0)) { + spim_close_pending_transfer(pHandle); + } + + /* Master SSEL de-assertion callback */ + if ((status & SPI_STAT_SSD) != 0) { + pDrv->base->STAT = SPI_STAT_SSD; + pDrv->base->INTENCLR = SPI_INTENSET_SSAEN | SPI_INTENSET_SSDEN | + SPI_INTENSET_RXDYEN | SPI_INTENSET_TXDYEN; + pXfer->status = pDrv->pendingStatus; + + /* De-assetion event */ + if (pDrv->pDeassertCb != NULL) { + pDrv->pDeassertCb(pHandle, pXfer); + } + } +} + +void spim_close_pending_transfer(ROM_SPIM_HANDLE_T pHandle) +{ + SPIM_DATACONTEXT_T *pDrv = (SPIM_DATACONTEXT_T *) pHandle; + + /* If stalled, force an EOT */ + if ((pDrv->base->STAT & SPI_STAT_STALLED) != 0) { + pDrv->base->STAT = SPI_STAT_EOT; + } + pDrv->base->TXCTRL |= SPI_TXCTL_EOT; + + _rom_spimCloseTransfer(pDrv); +} + +uint32_t spim_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.h new file mode 100644 index 0000000000000000000000000000000000000000..bc16b59cb65e3078a438b42a80e635e3c83a9641 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd.h @@ -0,0 +1,57 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 __HW_SPIMD_H +#define __HW_SPIMD_H + +#include "error.h" +#include "hw_spimd_rom_api.h" + +// *** SPI functions called by Application Program *** +uint32_t spim_get_mem_size(void); + +ROM_SPIM_HANDLE_T spim_init(void *mem, const ROM_SPIM_INIT_T *pInit); + +void spim_register_callback(ROM_SPIM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); + +ErrorCode_t spim_setup_transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_CONFIG_T *pCfg); + +ErrorCode_t spim_transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer); + +void spim_transfer_handler(ROM_SPIM_HANDLE_T pHandle); + +void spim_close_pending_transfer(ROM_SPIM_HANDLE_T pHandle); + +uint32_t spim_get_driver_version(void); + +// *** + +#endif /* __HW_SPIMD_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..55dc07b474828ccfacd62f36effc818be34bff01 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.c @@ -0,0 +1,45 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 "hw_spimd.h" + +// This creates a table with the addresses of all the SPI functions +// This table of function pointers is the API interface. +const ROM_SPIMD_API_T spim_api = { + &spim_get_mem_size, + &spim_init, + &spim_register_callback, + &spim_setup_transfer, + &spim_transfer, + &spim_transfer_handler, + &spim_close_pending_transfer, + &spim_get_driver_version, +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..78d1e4172951aeff2c36b12a0ca49b3b05510164 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spimd_rom_api.h @@ -0,0 +1,167 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 __HW_SPIMD_ROM_API_H +#define __HW_SPIMD_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_spi_common.h" + +/** @defgroup ROMAPI_SPIM SPI master ROM driver functions and definitions + * @ingroup ROMAPI_SPIM_WRAPPER + * @{ + */ + +/** @brief SPI master handle type */ +typedef void *ROM_SPIM_HANDLE_T; + +/* Number of selects the SPI driver supports */ +#define ROM_SPIM_MAXSELECTS (4) + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a SPI master + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_SPIM_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_SPIM_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief SPI master optional transfer flags */ +#define ROM_SPIM_FLAG_BLOCKING (1UL << 31) /*!< Transfer function will block until complete */ +#define ROM_SPIM_FLAG_DMATX (1UL << 30) /*!< DMA will be used for TX, requires DMA setup outside of the driver */ +#define ROM_SPIM_FLAG_DMARX (1UL << 29) /*!< DMA will be used for RX, requires DMA setup outside of the driver */ +#define ROM_SPIM_FLAG_LOOPBACK (1UL << 28) /*!< Enables loopback mode for the transfer, useful for testing only */ +#define ROM_SPIM_FLAG_TXIGNORE (1UL << 27) /*!< Ignores receive data regardless of txBuff, transmit data callback will not be called, stops when txSz = 0 */ +#define ROM_SPIM_FLAG_RXIGNORE (1UL << 26) /*!< Ignores receive data regardless of rxBuff/rxSz, receive data callback will not be called */ +#define ROM_SPIM_FLAG_USERBITS (0xFFFF) /*!< Application can safely use the flag bits designated by this mask */ + +/** @brief SPI transfer configuration structure - once of these needs to be setup for + * each SPI select (SSEL) used on the master. If only SSEL0 is used, it only needs to be setup + * for that one slave select. This structure must be statically allocated for use with the + * driver and should not be created on the program stack. If anything in this structure + * changes, SetupSSEL() must be called again with the structure reference. */ +typedef PRE_PACK struct POST_PACK { + uint32_t dXferBitRate; /*!< Desired bit transfer rate (SPI clock) in Hz */ + uint32_t rXferBitRate; /*!< Real bit transfer rate (SPI clock) in Hz, modified by driver to actual rate */ + uint8_t mode; /*!< Mode selection for this transfer (ROM_SPI_CLOCK_MODE_T) */ + uint8_t lsbFirst; /*!< 0 for msb sent/recv first, !0 = for lsb send/recv first */ + uint8_t dataBits; /*!< Data transfer size in bits, between 1 and 16, txBuff and rxBuff must be 16-bit aligned if >8 */ + /* The time delays are based in SPI clocks (rXferBitRate). These values are used to configure the + SPI delays when a transfer is started, so these values do not need to be populated for the + SetupSSEL() function. The actual (rXferBitRate) and desired (dXferBitRate) SPI clocks may differ, + and the actual clock won't be known until after SetupSSEL() is called, so it's best to setup + these values after the call to SetupSSEL(). */ + uint8_t PreDelay; /*!< Pre-delay value in (rXferBitRate) SPI clocks, 0 - 15 */ + uint8_t PostDelay; /*!< Post-delay value in (rXferBitRate) SPI clocks, 0 - 15 */ + uint8_t FrameDelay; /*!< Delay value between frames of a transfer in (rXferBitRate) SPI clocks, 0 - 15 */ + uint8_t TransferDelay; /*!< Delay value between transfers in (rXferBitRate) SPI clocks, 1 - 16 */ + uint8_t reserved; +} ROM_SPIM_XFER_CONFIG_T; + +/** @brief SPI Master transfer descriptor */ +typedef PRE_PACK struct POST_PACK { + const void *txBuff; /*!< Pointer to array of datum to be transmitted, use NULL for receive only, must be 16-bit aligned if datum bits >8 */ + uint32_t txSz; /*!< Size of the transmit buffer (txBuff) in items (not bytes) before transmit callback is called */ + void *rxBuff; /*!< Pointer memory where datum received from SPI be stored, use NULL for transmit only, must be 16-bit aligned if datum bits >8 */ + uint32_t rxSz; /*!< Size of the receive buffer (rxBuff) in items (not bytes) before receive callback is called */ + uint32_t flags; /*!< Optional transfer flags, may be modified by driver */ + volatile ErrorCode_t status; /*!< Status of the current SPI transfer (ErrorCode_t), must be 32-bits */ + uint8_t sselNum; /*!< SPI master SSEL number for this transfer, 0 - 3 */ + uint8_t reserved1[3]; +} ROM_SPIM_XFER_T; + +/** @brief SPI master callback IDs */ +typedef enum { + ROM_SPIM_ASSERTSSEL_CB = 0, /*!< Callback ID for SPI master SSEL assertion */ + ROM_SPIM_DATATRANSMIT_CB, /*!< Callback ID for SPI master transmit start */ + ROM_SPIM_DATATRECEIVE_CB, /*!< Callback ID for SPI master receive start */ + ROM_SPIM_DEASSERTSSEL_CB /*!< Callback ID for SPI master SSEL de-assertion */ +} ROM_SPIM_CALLBACK_T; + +/** @brief SPI master select assert callback + * This callback is called from the SPI master handler when the SPI master + * selects the slave (asserts SSEL). The callback is only called if it has been registered.
+ */ +typedef void (*spiMasterXferCSAssertCB)(ROM_SPIM_HANDLE_T spimHandle, ROM_SPIM_XFER_T *pXfer); + +/** @brief SPI master data receive start callback + * The SPI master state machine will call this optional function when it needs a buffer to + * receive data. The callback can be used to setup DMA or alter the receive buffer size. The + * callback is only called if it has been registered, the buffer has been fully used, and + * data is needed to populate the transmit FIFO. When using DMA, this callback must be enabled + * and used for DMA setup. + */ +typedef void (*spiMasterReceiveCB)(ROM_SPIM_HANDLE_T spimHandle, ROM_SPIM_XFER_T *pXfer); + +/** @brief SPI master data transmit start callback + * The SPI master state machine will call this optional function for data transfer. + * The callback can be used to setup DMA or alter the receive buffer size. The callback is + * only called if it has been registered, the buffer has been fully used, and data is pending + * is the receive FIFO. When using DMA, this callback must be enabled and used for DMA setup. + */ +typedef void (*spiMasterTransmitCB)(ROM_SPIM_HANDLE_T spimHandle, ROM_SPIM_XFER_T *pXfer); + +/** @brief SPI master transfer select deassert data callback + * This callback is called from the SPI master handler when the SPI master + * deasserts the slave select. The callback is only called if it has been registered.
+ */ +typedef void (*spiMMasterXferCSDeAssertCB)(ROM_SPIM_HANDLE_T spimHandle, ROM_SPIM_XFER_T *pXfer); + +/** @brief SPI master initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Base address of SPI peripheral to use */ + uint32_t baseClockRate; /*!< SPI base clock rate in Hz, call Init() again if this rate changes */ + uint8_t spiPol[4]; /*!< SPI SSEL pollarity for each slave select, 0 = active low, !0 = active high */ +} ROM_SPIM_INIT_T; + +/** @brief SPI master ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of SPI master driver */ + ROM_SPIM_HANDLE_T (*Init)(void *mem, const ROM_SPIM_INIT_T *pInit); /*!< Initializes the SPI master driver and peripheral */ + void (*RegisterCallback)(ROM_SPIM_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); /*!< Registers an SPI master callback */ + ErrorCode_t (*SetupTransfer)(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_CONFIG_T *pCfg); /*!< Sets up a master select's transfer configuration, should be called when the transfer configuration changes */ + ErrorCode_t (*Transfer)(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer); /*!< Perform or start and SPI master transfer */ + void (*TransferHandler)(ROM_SPIM_HANDLE_T pHandle); /*!< SPI master transfer (interrupt) handler */ + void (*ClosePendingTransfer)(ROM_SPIM_HANDLE_T pHandle); /*!< Immediately terminates the current transfer */ + uint32_t (*GetDriverVersion)(void); +} ROM_SPIMD_API_T; + +/** + * @} + */ + +extern const ROM_SPIMD_API_T spim_api; // so application program can access pointer to +// function table + +#endif /* __HW_SPIMD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.c new file mode 100644 index 0000000000000000000000000000000000000000..6994f99211482c3d5ec823f4c0dee548b93346c8 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.c @@ -0,0 +1,535 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 +#include +#include "hw_spisd.h" + +#define DRVVERSION 0x0100 + +/* Private callback for FIFO push and pop functions. This privately maps + to the VFIFO for the SPI slave, but can be overriden if needed. The driver will + automatically pick the right implementation at run-time based on the transfer + size in the transfer descriptor. */ +typedef uint16_t (*spisSlaveFifoPushFN)(LPC_SPI_T *pSPI, void *data, uint32_t sendBytes, uint32_t curIndex); +typedef uint16_t (*spisSlaveFifoPopFN)(LPC_SPI_T *pSPI, void *data, uint32_t bytes, uint32_t curIndex); + +/* Private data structure used for the SPI slave driver, holds the driver and + peripheral context */ +typedef struct { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + LPC_SPI_T *base; /*!< Base address of SPI peripheral to use */ + spisSlaveXferCSAssertCB pAssertCb; /*!< SSEL assertion callback */ + spisSlaveTransmitCB pTranCb; /*!< Transmit data start callback */ + spisSlaveReceiveCB pRecvCb; /*!< Receive data start callback */ + spisSlaveXferCSDeAssertCB pDeassertCb; /*!< SSEL deassertion callback */ + spisSlaveFifoPushFN pPushFN; /*!< Pointer to current FIFO push function */ + spisSlaveFifoPopFN pPopFN; /*!< Pointer to current FIFO pop function */ + ROM_SPIS_XFER_T *pXfer; /*!< Pointer to current transfer descriptor */ + uint32_t sendIdx; /*!< Current transmit buffer index */ + uint32_t recvIdx; /*!< Current receive buffer index */ + ErrorCode_t pendingStatus; /*!< Pending transfer status */ +} SPIS_DATACONTEXT_T; + +/* Maps config registers bits for SPI mode to the transfer descriptor */ +static const uint32_t spiModeBits[4] = { + (SPI_CFG_CPOL_LO | SPI_CFG_CPHA_FIRST), + (SPI_CFG_CPOL_LO | SPI_CFG_CPHA_SECOND), + (SPI_CFG_CPOL_HI | SPI_CFG_CPHA_FIRST), + (SPI_CFG_CPOL_HI | SPI_CFG_CPHA_SECOND) +}; + +/* FIFO push function using standard SPI FIFO for datum >8 bits */ +static uint16_t _rom_spisSlaveFifoPush16(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t pushed = 0, *p16 = (uint16_t *) data; + + /* Push as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_TXRDY) != 0)) { + pSPI->TXDAT = (uint32_t) p16[curIndex]; + numData--; + curIndex++; + pushed++; + } + + return pushed; +} + +/* FIFO pop function using standard SPI FIFO for datum >8 bits */ +static uint16_t _rom_spisSlaveFifoPop16(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t popped = 0, *p16 = (uint16_t *) data; + + /* Pop as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_RXRDY) != 0)) { + p16[curIndex] = (uint16_t) pSPI->RXDAT; + numData--; + curIndex++; + popped++; + } + + return popped; +} + +/* FIFO push function using standard SPI FIFO for datum <=8 bits */ +static uint16_t _rom_spisSlaveFifoPush8(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t pushed = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Push as 8-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_TXRDY) != 0)) { + pSPI->TXDAT = (uint32_t) p8[curIndex]; + numData--; + curIndex++; + pushed++; + } + + return pushed; +} + +/* FIFO pop function using standard SPI FIFO for datum <=8 bits */ +static uint16_t _rom_spisSlaveFifoPop8(LPC_SPI_T *pSPI, void *data, uint32_t numData, uint32_t curIndex) +{ + uint16_t popped = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Pop as 16-bit value */ + while ((numData > 0) && ((pSPI->STAT & SPI_STAT_RXRDY) != 0)) { + p8[curIndex] = (uint8_t) pSPI->RXDAT; + numData--; + curIndex++; + popped++; + } + + return popped; +} + +static void _rom_spisTransmitHandler(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + + /* This shouldn't be called if there is no transfer descriptor */ + if (!pXfer) { + pDrv->base->INTENCLR = SPI_INTENSET_TXDYEN; + return; + } + + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIS_FLAG_DMATX) != 0) { + /* Call transmit callback, callback is pre-validated by setup */ + if (pDrv->pTranCb) { + pDrv->pTranCb(pHandle, pXfer); + } + + pDrv->base->INTENCLR = SPI_INTENSET_TXDYEN; + } + else { /* Transfer without using DMA */ + if ((pXfer->flags & ROM_SPIS_FLAG_TXIGNORE) != 0) { + /* ROM_SPIS_FLAG_TXIGNORE flag is set. Will send 0xFF */ + static const uint16_t sb = 0xFFFF; + pDrv->sendIdx += pDrv->pPushFN(pDrv->base, (void *) &sb, 1, 0); + } + else { + uint32_t bs; + + /* Normal data transfer */ + if (pDrv->sendIdx >= pXfer->txSz) { + /* Ran out of data, get more data */ + if (pDrv->pTranCb) { + pDrv->pTranCb(pHandle, pXfer); + pDrv->sendIdx = 0; + } + } + + if (pDrv->sendIdx < pXfer->txSz) { + bs = pDrv->pPushFN(pDrv->base, (void *) pXfer->txBuff, 1, pDrv->sendIdx); + pDrv->sendIdx += bs; + pXfer->txSent += bs; + } + else { + /* Out of transmit data and no more is provided via the callback, + so disable the transmit interrupt and let the hardware underflow + and send 0. It will only underflow if the master requests data + beyond what is in the transmit FIFO now. The underflow error code + needs to be handled as part of the hardware since this may not be + an underflow condition is the master stops on this datum. */ + pDrv->base->INTENCLR = SPI_INTENSET_TXDYEN; + } + } + } +} + +static void _rom_spisReceiveHandler(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + + /* This shouldn't be called if there is no transfer descriptor */ + if (!pXfer) { + pDrv->base->INTENCLR = SPI_INTENSET_RXDYEN; + return; + } + + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIS_FLAG_DMARX) != 0) { + /* Call receive callback, callback is pre-validated by setup */ + if (pDrv->pRecvCb) { + pDrv->pRecvCb(pHandle, pXfer); + } + + pDrv->base->INTENCLR = SPI_INTENSET_RXDYEN; + } + else { /* Transfer without using DMA */ + if ((pXfer->flags & ROM_SPIS_FLAG_RXIGNORE) != 0) { + /* ROM_SPIS_FLAG_RXIGNORE flag is set. Toss data */ + uint16_t temp; + pDrv->recvIdx += pDrv->pPopFN(pDrv->base, (void *) &temp, 1, 0); + } + else { + uint32_t br; + + /* Normal data transfer */ + if (pDrv->recvIdx >= pXfer->rxSz) { + uint16_t temp; + /* Ran out of data, overflowing */ + pDrv->pendingStatus = ERR_SPI_RXOVERRUN; + br = pDrv->pPopFN(pDrv->base, (void *) &temp, 1, 0);/* Flush data */ + } + else { + br = pDrv->pPopFN(pDrv->base, (void *) pXfer->rxBuff, 1, pDrv->recvIdx); + pXfer->rxRecv += br; + pDrv->recvIdx += br; + + /* Call callback for more data */ + if ((pDrv->recvIdx >= pXfer->rxSz) && (pDrv->pRecvCb)) { + pDrv->pRecvCb(pHandle, pXfer); + pDrv->recvIdx = 0; + } + } + } + } +} + +/* Determine SSEL associated with the current data value */ +static uint8_t Chip_SPIS_FindSSEL(LPC_SPI_T *pSPI, uint32_t data) +{ + int i; + + /* Return first active SSEL starting at SSEL0 */ + for (i = 0; i <= 3; i++) { + if ((data & SPI_RXDAT_RXSSELNUM_INACTIVE(i)) == 0) { + /* Signal is active on low */ + return (uint8_t) i; + } + } + + return 0; +} + +// ********************************************************** +uint32_t spis_get_mem_size(void) +{ + return sizeof(SPIS_DATACONTEXT_T); +} + +ROM_SPIS_HANDLE_T spis_init(void *mem, const ROM_SPIS_INIT_T *pInit) +{ + SPIS_DATACONTEXT_T *pDrv; + int i; + + /* Verify alignment is at least 4 bytes */ + if (((uint32_t) mem & 0x3) != 0) { + return NULL; + } + + pDrv = (SPIS_DATACONTEXT_T *) mem; + memset(pDrv, 0, sizeof(SPIS_DATACONTEXT_T)); + + /* Save base of peripheral and pointer to user data */ + pDrv->pUserData = pInit->pUserData; + pDrv->base = (LPC_SPI_T *) pInit->base; + + /* Enable SPI slave interface */ + pDrv->base->CFG = 0; + pDrv->base->CFG = SPI_CFG_SPI_EN; + + /* Set SPI slave select (SSEL) polarity for each slave signal */ + for (i = 0; i <= 3; i++) { + if (pInit->spiPol[i] == 0) { + /* Active low select, high during idle */ + pDrv->base->CFG &= ~(1 << (8 + i)); + } + else { + /* Active high, low during idle */ + pDrv->base->CFG |= (1 << (8 + i)); + } + } + + /* Enable SPI slave interface, deassert all chip selects (not needed for slave) */ + pDrv->base->TXCTRL = SPI_TXDATCTL_DEASSERT_ALL; + + /* Clear pending slave statuses - RXOV, TXUR, SSA, SSD, EOT */ + pDrv->base->STAT = (SPI_STAT_RXOV | SPI_STAT_TXUR | SPI_STAT_SSA | + SPI_STAT_SSD | SPI_STAT_EOT); + + return (ROM_SPIS_HANDLE_T) pDrv; +} + +void spis_register_callback(ROM_SPIS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + + switch (cbIndex) { + case ROM_SPIS_ASSERTSSEL_CB: + pDrv->pAssertCb = (spisSlaveXferCSAssertCB) pCB; + break; + + case ROM_SPIS_DATATRANSMIT_CB: + pDrv->pTranCb = (spisSlaveTransmitCB) pCB; + break; + + case ROM_SPIS_DATATRECEIVE_CB: + pDrv->pRecvCb = (spisSlaveReceiveCB) pCB; + break; + + case ROM_SPIS_DEASSERTSSEL_CB: + pDrv->pDeassertCb = (spisSlaveXferCSDeAssertCB) pCB; + break; + } +} + +ErrorCode_t spis_setup_slave(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_SLAVE_T *pCfg) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + uint32_t reg; + + /* Verify config is valid */ + if (pCfg == NULL) { + return ERR_SPI_PARAM; + } + + /* Verify data parameters area valid */ + if ((pCfg->dataBits == 0) || (pCfg->dataBits > 16)) { + return ERR_SPI_PARAM; + } + + /* Verify mode */ + if (pCfg->mode > ROM_SPI_CLOCK_MODE3) { + return ERR_SPI_PARAM; + } + + /* Setup transfer mode and LSB/MSB first */ + reg = pDrv->base->CFG; + reg &= ~(SPI_CFG_LSB_FIRST_EN | SPI_CFG_CPHA_SECOND | + SPI_CFG_CPOL_HI); + + /* Setup SPI transfer configuration (CFG register) */ + reg |= spiModeBits[(int) pCfg->mode]; + if (pCfg->lsbFirst) { + reg |= SPI_CFG_LSB_FIRST_EN; + } + pDrv->base->CFG = reg; + + /* Setup SPI transfer configuration (TXCTRL) for data size, don't alter SPI SSEL states */ + reg = pDrv->base->TXCTRL & ~SPI_TXCTL_FLEN(16); + pDrv->base->TXCTRL = reg | SPI_TXCTL_FLEN(pCfg->dataBits); + + /* Setup FIFO callbacks based on the data transfer width */ + if (pCfg->dataBits > 8) { + pDrv->pPushFN = &_rom_spisSlaveFifoPush16; + pDrv->pPopFN = &_rom_spisSlaveFifoPop16; + } + else { + pDrv->pPushFN = &_rom_spisSlaveFifoPush8; + pDrv->pPopFN = &_rom_spisSlaveFifoPop8; + } + + /* Enable SPI interrupts for slave */ + pDrv->base->INTENSET = SPI_INTENSET_SSAEN | SPI_INTENSET_SSDEN | + SPI_INTENSET_RXOVEN | SPI_INTENSET_TXUREN; + + return LPC_OK; +} + +void spis_transfer_handler(ROM_SPIS_HANDLE_T pHandle) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + ROM_SPIS_XFER_T *pXfer = pDrv->pXfer; + + /* Master asserts slave */ + if ((pDrv->base->INTSTAT & SPI_INTSTAT_SSA) != 0) { + pDrv->base->STAT = SPI_STAT_SSA; + + /* Slave SSEL assertion callback */ + if (pDrv->pAssertCb != NULL) { + /* If if takes too long to handle this event, there may also be + recevied data with the asserted SSEL status. The best way to prevent + this is to have the master provide a SSEL setup delay between the + start of the SSEL assertion and the transfer of the first datum, or + disable the assertion callback and ignore this event. */ + /* Note that setting up transfer buffers based on the slave address is + the assertion callback may result in a transmit underflow. */ + uint32_t data = pDrv->base->RXDAT; + pDrv->pAssertCb(pHandle, Chip_SPIS_FindSSEL(pDrv->base, data)); + + /* Update transfer descriptor */ + pXfer = pDrv->pXfer; + } + + /* Disable assertion interrupt, enable deassertion interrupt */ + pDrv->base->INTENCLR = SPI_INTENSET_SSAEN; + pDrv->base->INTENSET = SPI_INTENSET_SSDEN | SPI_INTENSET_RXDYEN | SPI_INTENSET_TXDYEN; + } + + /* If overrun or underrun errors occured, latch the error */ + if ((pDrv->base->INTSTAT & SPI_INTSTAT_TXUR) != 0) { + pDrv->pendingStatus = ERR_SPI_TXUNDERRUN; + pDrv->base->STAT = SPI_STAT_TXUR; + } + + /* Receive overflow takes precedence over TX */ + if ((pDrv->base->INTSTAT & SPI_INTSTAT_RXOV) != 0) { + pDrv->pendingStatus = ERR_SPI_RXOVERRUN; + pDrv->base->STAT = SPI_STAT_RXOV; + } + + if ((pDrv->base->INTSTAT & SPI_INTSTAT_TXRDY) != 0) { + /* Handle transmit */ + _rom_spisTransmitHandler(pHandle, pXfer); + } + + /* Receive data handler */ + if ((pDrv->base->INTSTAT & SPI_INTSTAT_RXRDY) != 0) { + /* Handle receive */ + _rom_spisReceiveHandler(pHandle, pXfer); + } + + /* Slave SSEL de-assertion callback */ + if ((pDrv->base->INTSTAT & SPI_INTSTAT_SSD) != 0) { + pDrv->base->STAT = SPI_STAT_SSD | SPI_STAT_RXOV | SPI_STAT_TXUR; + pDrv->base->INTENSET = SPI_INTENSET_SSAEN; + pDrv->base->INTENCLR = SPI_INTENSET_SSDEN | SPI_INTENSET_RXDYEN | SPI_INTENSET_TXDYEN; + + if (pXfer) { + pXfer->status = pDrv->pendingStatus; + pDrv->pXfer = NULL; + } + + /* On de-assertion, flush any data left in the transmmit and receive FIFO. + This is needed when streaming data and the size of the transfer isn't + known, so data may be left to transmit when the master deasserts. */ + pDrv->base->CFG &= ~SPI_CFG_SPI_EN; + pDrv->base->CFG |= SPI_CFG_SPI_EN; + + /* De-assetion event */ + if (pDrv->pDeassertCb != NULL) { + pDrv->pDeassertCb(pHandle, pXfer); + } + } +} + +ErrorCode_t spis_transfer(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer) +{ + SPIS_DATACONTEXT_T *pDrv = (SPIS_DATACONTEXT_T *) pHandle; + uint8_t flen; + + /* Get length of a receive value */ + flen = 1 + (uint8_t) ((pDrv->base->TXCTRL >> 24) & 0xF); + + /* Is transfer descriptor valid? */ + if (pXfer == NULL) { + return ERR_SPI_PARAM; + } + + /* No need to check RX buffer alignment if ROM_SPIS_FLAG_RXIGNORE flag is set */ + if ((pXfer->flags & ROM_SPIS_FLAG_RXIGNORE) == 0) { + if ((pXfer->rxSz == 0) || (pXfer->rxBuff == NULL)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + if ((flen > 8) && ((((uint32_t) pXfer->rxBuff) & 0x1) != 0)) { + /* Receive buffer not 16-bit aligned or not present */ + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIS_FLAG_DMARX) != 0) { + if (pDrv->pRecvCb == NULL) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + } + } + + /* Check transmit buffer alignment */ + if ((pXfer->flags & ROM_SPIS_FLAG_TXIGNORE) == 0) { + if ((pXfer->txSz == 0) || (pXfer->txBuff == NULL)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + if ((flen > 8) && ((((uint32_t) pXfer->txBuff) & 0x1) != 0)) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + /* Is DMA being used? */ + if ((pXfer->flags & ROM_SPIS_FLAG_DMATX) != 0) { + if (pDrv->pTranCb == NULL) { + pXfer->status = ERR_SPI_PARAM; + return ERR_SPI_PARAM; + } + } + } + + /* ROM_SPIS_FLAG_RXIGNORE flag */ + if ((pXfer->flags & ROM_SPIS_FLAG_RXIGNORE) != 0) { + pDrv->base->TXCTRL |= SPI_TXCTL_RXIGNORE; + } + else { + pDrv->base->TXCTRL &= ~SPI_TXCTL_RXIGNORE; + } + + /* Save pointer to transfer descriptor and initial status */ + pDrv->pXfer = pXfer; + pXfer->status = ERR_SPI_BUSY; + pDrv->pendingStatus = LPC_OK; + pDrv->sendIdx = pDrv->recvIdx = pXfer->txSent = pXfer->rxRecv = 0; + + pDrv->base->INTENSET = SPI_INTENSET_RXDYEN | SPI_INTENSET_TXDYEN; + + return pXfer->status; +} + +uint32_t spis_get_driver_version(void) +{ + return DRVVERSION; +} + +// ********************************************************* diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.h new file mode 100644 index 0000000000000000000000000000000000000000..2c7b5082351de738df3a2e44d58075cb988e3715 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd.h @@ -0,0 +1,55 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 __HW_SPISD_H +#define __HW_SPISD_H + +#include "error.h" +#include "hw_spisd_rom_api.h" + +// *** SPI functions called by Application Program *** +uint32_t spis_get_mem_size(void); + +ROM_SPIS_HANDLE_T spis_init(void *mem, const ROM_SPIS_INIT_T *pInit); + +void spis_register_callback(ROM_SPIS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); + +ErrorCode_t spis_setup_slave(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_SLAVE_T *pCfg); + +void spis_transfer_handler(ROM_SPIS_HANDLE_T pHandle); + +ErrorCode_t spis_transfer(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer); + +uint32_t spis_get_driver_version(void); + +// *** + +#endif /* __HW_SPISD_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.c new file mode 100644 index 0000000000000000000000000000000000000000..7ae7676f2377f147541a9967e22ef4f98748cef0 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.c @@ -0,0 +1,44 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 "hw_spisd.h" + +// This creates a table with the addresses of all the SPI functions +// This table of function pointers is the API interface. +const ROM_SPISD_API_T spis_api = { + &spis_get_mem_size, + &spis_init, + &spis_register_callback, + &spis_setup_slave, + &spis_transfer, + &spis_transfer_handler, + &spis_get_driver_version, +}; // end of table ************************************ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..0a73a556be64be17445ba934f061ddbf28a48d88 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_spisd_rom_api.h @@ -0,0 +1,151 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 __HW_SPISD_ROM_API_H +#define __HW_SPISD_ROM_API_H + +#include "stdint.h" // added to define uint32_t, etc. +#include "error.h" +#include "packing.h" +#include "hw_spi_common.h" + +/** @defgroup ROMAPI_SPIS SPI slave ROM driver functions and definitions + * @ingroup ROMAPI_SPIS_WRAPPER + * @{ + */ + +/** @brief SPI slave handle type */ +typedef void *ROM_SPIS_HANDLE_T; + +/** @brief Number of selects the SPI driver supports */ +#define ROM_SPIS_MAXSELECTS (4) + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a SPI slave + * handle context.
+ * To get a user context, simple use the macro on the drivers handle: + * void *pUserData = (void *) ROM_SPIS_HANDLE_TOUDATA(driverHandle); + */ +#define ROM_SPIS_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief SPI slave optional transfer flags */ +#define ROM_SPIS_FLAG_DMATX (1UL << 30) /*!< DMA will be used for TX, requires DMA setup outside of the driver */ +#define ROM_SPIS_FLAG_DMARX (1UL << 29) /*!< DMA will be used for RX, requires DMA setup outside of the driver */ +#define ROM_SPIS_FLAG_TXIGNORE (1UL << 27) /*!< Ignores transmit data regardless of txBuff, transmit data callback will not be called, stops when txSz = 0 */ +#define ROM_SPIS_FLAG_RXIGNORE (1UL << 26) /*!< Ignores receive data regardless of rxBuff/rxSz, receive data callback will not be called */ +#define ROM_SPIS_FLAG_USERBITS (0xFFFF) /*!< Application can safely use the flag bits designated by this mask */ + +/** @brief SPI transfer configuration structure - once of these needs to be setup for + * each SPI select (SSEL) used on the slave. If only SSEL0 is used, it only needs to be setup + * for that one slave select. */ +typedef PRE_PACK struct POST_PACK { + uint8_t mode; /*!< Mode selection for this transfer (ROM_SPI_CLOCK_MODE_T) */ + uint8_t lsbFirst; /*!< 0 for msb sent/recv first, !0 = for lsb send/recv first */ + uint8_t dataBits; /*!< Data transfer size in bits, between 1 and 16, txBuff and rxBuff must be 16-bit aligned if >8 */ + uint8_t reserved; +} ROM_SPIS_SLAVE_T; + +/** @brief SPI slave transfer descriptor */ +typedef PRE_PACK struct POST_PACK { + const void *txBuff; /*!< Pointer to array of datum to be transmitted, must be 16-bit aligned if datum bits >8 */ + uint32_t txSz; /*!< Size of the transmit buffer (txBuff) in items (not bytes) before transmit callback is called */ + uint32_t txSent; /*!< Number of items (not bytes) sent between SSEL assertion and deassertion */ + void *rxBuff; /*!< Pointer memory where datum received from SPI be stored, must be 16-bit aligned if datum bits >8 */ + uint32_t rxSz; /*!< Size of the receive buffer (rxBuff) in items (not bytes) before receive callback is called */ + uint32_t rxRecv; /*!< Number of items (not bytes) received between SSEL assertion and deassertion */ + uint32_t flags; /*!< Optional transfer flags, may be modified by driver */ + volatile ErrorCode_t status; /*!< Status of the current SPI transfer (ErrorCode_t), must be 32-bits */ +} ROM_SPIS_XFER_T; + +/** @brief SPI slave callback IDs */ +typedef enum { + ROM_SPIS_ASSERTSSEL_CB = 0, /*!< Callback ID for SPI slave select (SSEL) assertion */ + ROM_SPIS_DATATRANSMIT_CB, /*!< Callback ID for SPI slave transmit start */ + ROM_SPIS_DATATRECEIVE_CB, /*!< Callback ID for SPI slave receive start */ + ROM_SPIS_DEASSERTSSEL_CB /*!< Callback ID for SPI slave select (SSEL) de-assertion (completion callback) */ +} ROM_SPIS_CALLBACK_T; + +/** @brief SPI slave select assert callback + * This callback is called from the SPI slave handler when the SPI slave + * selects the slave (asserts SSEL). The callback is only called if it has been registered. + */ +typedef void (*spisSlaveXferCSAssertCB)(ROM_SPIS_HANDLE_T spisHandle, uint8_t slaveNum); + +/** @brief SPI slave data receive start callback + * The SPI slave state machine will call this optional function when it needs a buffer to + * receive data. The callback can be used to setup DMA or alter the receive buffer size. The + * callback is only called if it has been registered, the buffer has been fully used, and + * data is pending is the receive FIFO. When using DMA, this callback must be enabled and + * used for DMA setup. + */ +typedef void (*spisSlaveReceiveCB)(ROM_SPIS_HANDLE_T spisHandle, ROM_SPIS_XFER_T *pXfer); + +/** @brief SPI slave data transmit start callback + * The SPI slave state machine will call this optional function prior to data transfer. + * The callback can be used to setup DMA or alter the receive buffer size. The callback + * is only called if it has been registered, the buffer has been fully used, and data is + * needed to populate the transmit FIFO. When using DMA, this callback must be enabled and + * used for DMA setup. + */ +typedef void (*spisSlaveTransmitCB)(ROM_SPIS_HANDLE_T spisHandle, ROM_SPIS_XFER_T *pXfer); + +/** @brief SPI slave transfer select deassert data callback + * This callback is called from the SPI slave handler when the SPI slave + * deasserts the slave select. The callback is only called if it has been registered. + */ +typedef void (*spisSlaveXferCSDeAssertCB)(ROM_SPIS_HANDLE_T spisHandle, ROM_SPIS_XFER_T *pXfer); + +/** @brief SPI slave initialization structure */ +typedef PRE_PACK struct POST_PACK { + void *pUserData; /*!< Pointer to user data used by driver instance, use NULL if not used */ + uint32_t base; /*!< Base address of SPI peripheral to use */ + uint8_t spiPol[4]; /*!< SPI SSEL pollarity for each slave select, 0 = active low, !0 = active high */ +} ROM_SPIS_INIT_T; + +/** @brief SPI slave ROM indirect function structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of SPI slave driver */ + ROM_SPIS_HANDLE_T (*Init)(void *mem, const ROM_SPIS_INIT_T *pInit); /*!< Initializes the SPI slave driver and peripheral */ + void (*RegisterCallback)(ROM_SPIS_HANDLE_T pHandle, uint32_t cbIndex, void *pCB); /*!< Registers an SPI slave callback */ + ErrorCode_t (*SetupSlave)(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_SLAVE_T *pSlaveSetup); /*!< Setup SPI slave transfer configuration */ + ErrorCode_t (*Transfer)(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer); /*!< Prepare a SPI slave transfer */ + void (*TransferHandler)(ROM_SPIS_HANDLE_T pHandle); /*!< SPI slave transfer (interrupt) handler */ + uint32_t (*GetDriverVersion)(void); +} ROM_SPISD_API_T; + +/** + * @} + */ + +extern const ROM_SPISD_API_T spis_api; // so application program can access pointer to +// function table + +#endif /* __HW_SPISD_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..f8fcf0207b0f9cd973a4a1b8aade06e66177cf47 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.c @@ -0,0 +1,595 @@ +/* + * @brief UART ROM API declarations and functions + * + * @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 "error.h" +#include "hw_uart_rom_api.h" + +#define UART_IDLE_FIX /* Remove once IDLE problem is fixed */ + +/* UART Driver internal data structure */ +typedef struct { + void *pUserData; /* Pointer to user data */ + UART_REGS_T *pREGS; /* Pointer to Registers */ + UART_DATA_T xfer[2]; /* TX/RX transfer data */ +#ifdef UART_IDLE_FIX + uint32_t dly; /* Delay to count 1 bit time; REMOVE: when H/W is fixed */ +#endif + void(*cbTable[UART_CB_RESERVED]) (UART_HANDLE_T, UART_EVENT_T, void *); /* Call-back index table */ +} UART_DRIVER_T; + +/* PRIVATE: Division logic to divide without integer overflow */ +static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m) +{ + uint32_t q, r, u = pclk >> 24, l = pclk << 8; + m = m + 256; + q = (1 << 24) / m; + r = (1 << 24) - (q * m); + return ((q * u) << 8) + (((r * u) << 8) + l) / m; +} + +/* PRIVATE: Get highest Over sampling value */ +static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict) +{ + int32_t i, max = strict ? 16 : 5; + for (i = 16; i >= max; i--) { + if (!(val % i)) { + return i; + } + } + return 0; +} + +/* PRIVATE: Queue a transfer in UART */ +static ErrorCode_t _UART_Xfer(UART_DRIVER_T *pUART, void *buff, uint16_t len, uint8_t op) +{ + UART_DATA_T *xfr = &pUART->xfer[op]; + + /* Xfer of 0 bytes in a UART should always be successful */ + if (!len) { + return LPC_OK; + } + + /* Check if a Xfer is alredy in progress */ + if (xfr->count > xfr->offset) { + return ERR_BUSY; + } + + xfr->buf = (void *) buff; + xfr->count = len; + xfr->offset = 0; + xfr->state = UART_ST_BUSY; + if (!op) { + pUART->pREGS->INTENSET = UART_INT_TXRDY; + } + else { + pUART->pREGS->INTENSET = UART_INT_RXRDY | UART_INT_FRMERR | UART_INT_RXNOISE | UART_INT_START | UART_INT_OVR; + } + + return LPC_OK; +} + +/* Calculate error difference */ +static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev) +{ + uint32_t err = n - (n / d) * d; + uint32_t herr = ((n / d) + 1) * d - n; + if (herr < err) { + err = herr; + } + + if (*prev <= err) { + return 0; + } + *prev = err; + return (herr == err) + 1; +} + +/* Calculate the base DIV value */ +static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub) +{ + int32_t i = 0; + uint32_t perr = ~0UL; + + if (!ub->div) { + i = ub->ovr ? ub->ovr : 16; + } + + for (; i > 4; i--) { + int32_t tmp = _CalcErr(ub->clk, ub->baud * i, &perr); + + /* Continue when no improvement seen in err value */ + if (!tmp) { + continue; + } + + ub->div = tmp - 1; + if (ub->ovr == i) { + break; + } + ub->ovr = i; + } + + if (!ub->ovr) { + return ERR_UART_BAUDRATE; + } + + ub->div += ub->clk / (ub->baud * ub->ovr); + if (!ub->div) { + return ERR_UART_BAUDRATE; + } + + ub->baud = ub->clk / (ub->div * ub->ovr); + return LPC_OK; +} + +/* Calculate the best MUL value */ +static void _UART_CalcMul(UART_BAUD_T *ub) +{ + uint32_t m, perr = ~0UL, pclk = ub->clk, ovr = ub->ovr; + + /* If clock is UART's base clock calculate only the divider */ + for (m = 0; m < 256; m++) { + uint32_t ov = ovr, x, v, tmp; + + /* Get clock and calculate error */ + x = _UART_DivClk(pclk, m); + tmp = _CalcErr(x, ub->baud, &perr); + v = (x / ub->baud) + tmp - 1; + + /* Update if new error is better than previous best */ + if (!tmp || (ovr && (v % ovr)) || + (!ovr && ((ov = _UART_GetHighDiv(v, ovr)) == 0))) { + continue; + } + + ub->ovr = ov; + ub->mul = m; + ub->clk = x; + ub->div = tmp - 1; + } +} + +/* PRIVATE: Invoke UART Call back functions */ +static void _UART_InvokeCB(UART_DRIVER_T *pUART, UART_EVENT_T event, void *arg) +{ + void (*cbfn)(UART_HANDLE_T, UART_EVENT_T, void *); + cbfn = pUART->cbTable[(uint32_t) event >> 1]; + if (cbfn != NULL) { + cbfn((UART_HANDLE_T) pUART, event, arg); + } +} + +/* PRIVATE: Handler for data transfers */ +static void _UART_HandleTxRx(UART_HANDLE_T hUART, UART_EVENT_T event, void *arg) +{ + UART_DATA_T *dat = (UART_DATA_T *) arg; + UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART; + uint16_t *buf16 = dat->buf; + uint8_t *buf8 = dat->buf; + + /* Transmit data */ + if (event == UART_TX_DATA) { + while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_TXRDY)) { + if (dat->dwidth) { + pUART->pREGS->TXDAT = *buf16++; + } + else { + pUART->pREGS->TXDAT = *buf8++; + } + dat->count--; + } + return; + } + + /* Receive data */ + while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_RXRDY)) { + if (dat->dwidth) { + *buf16++ = pUART->pREGS->RXDAT & 0x1FF; + } + else { + *buf8++ = pUART->pREGS->RXDAT & 0xFF; + } + dat->count--; + } +} + +/* Handle UART Receive event */ +static int32_t _UART_HandleXfer(UART_DRIVER_T *pUART, uint8_t op) +{ + UART_DATA_T dat; + UART_DATA_T *xfr = &pUART->xfer[op]; + + /* See if the transfer is already complete */ + if (xfr->offset >= xfr->count) { + return 2; + } + + /* Fill the buffer data structure */ + dat.count = xfr->count - xfr->offset; + dat.dwidth = ((pUART->pREGS->CFG >> 2) & 3) > 1; + if (dat.dwidth) { + dat.buf = &((uint16_t *) xfr->buf)[xfr->offset]; + } + else { + dat.buf = &((uint8_t *) xfr->buf)[xfr->offset]; + } + + if (!xfr->offset && xfr->count) { + _UART_InvokeCB(pUART, UART_TX_START, xfr); + } + + pUART->cbTable[UART_CB_DATA]((UART_HANDLE_T) pUART, (UART_EVENT_T) (UART_TX_DATA + op), &dat); + xfr->offset = (xfr->count - dat.count); + + if (xfr->offset >= xfr->count) { + if (!op) { + pUART->pREGS->INTENCLR = UART_INT_TXRDY; + } + else { + pUART->pREGS->INTENCLR = UART_INT_RXRDY; + } + + _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_TX_DONE + op), xfr); + if (xfr->state == UART_ST_BUSY) { + xfr->state = UART_ST_DONE; + } + return 1; + } + return 0; +} + +/* STOP Receive under progress */ +static void _UART_StopRx(UART_HANDLE_T hUART) +{ + UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART; + UART_DATA_T *rx = &pUART->xfer[1]; + volatile uint16_t *idx = (volatile uint16_t *) &rx->offset; + + if (*idx >= rx->count) { + return; + } + + /* Disable further receive interrupts */ + pUART->pREGS->INTENCLR = UART_INT_RXRDY; + rx->count = *idx; + _UART_InvokeCB(pUART, UART_RX_DONE, rx); +} + +/* EXPROTED API: Returns memory required for UART ROM driver */ +uint32_t UART_GetMemSize(void) +{ + return sizeof(UART_DRIVER_T); +} + +/* EXPORTED API: Calculate UART Baudrate divisors */ +ErrorCode_t UART_CalculateBaud(UART_BAUD_T *ub) +{ + if (!ub->mul) { + _UART_CalcMul(ub); + } + + return _UART_CalcDiv(ub); +} + +/* EXPORTED API: UART Initialization function */ +UART_HANDLE_T UART_Init(void *mem, uint32_t base_addr, void *args) +{ + UART_DRIVER_T *pUART; + + /* Check if the memory is word aligned */ + if ((uint32_t) mem & 0x3) { + return NULL; + } + + /* Assign memory provided by application */ + pUART = (UART_DRIVER_T *) mem; + memset(pUART, 0, sizeof(UART_DRIVER_T)); + + /* Assign the base address */ + pUART->pREGS = (UART_REGS_T *) base_addr; + pUART->pUserData = args; + + /* Set default handler for TX and RX */ + pUART->cbTable[UART_CB_DATA] = _UART_HandleTxRx; + return (UART_HANDLE_T) pUART; +} + +/* EXPORTED API: Configure UART parameters */ +ErrorCode_t UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *cfg) +{ + UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART; + UART_REGS_T *pREGS = pUART->pREGS; + + if (((cfg->cfg & UART_PAR_MASK) == (1 << 4)) || + ( (cfg->cfg & UART_DATA_MASK) == (3 << 2)) ) { + return ERR_UART_PARAM; + } + + /* Enable parity error when parity is enabled */ + if ((cfg->cfg & UART_PAR_MASK) >> 4) { + pREGS->INTENSET = UART_INT_PARERR; + } + + if (((int32_t) cfg->div <= 0) || ((int32_t) cfg->ovr <= 0)) { + return ERR_UART_PARAM; + } + + pREGS->OSR = (cfg->ovr - 1) & 0x0F; + pREGS->BRG = (cfg->div - 1) & 0xFFFF; + pREGS->CFG = UART_CFG_ENABLE | (cfg->cfg & ~UART_CFG_RES); + + /* Enabled RX of BREAK event */ + if (cfg->cfg & UART_CFG_BRKRX) { + pREGS->INTENSET = UART_INT_BREAK; + } + + /* Enable CTS interrupt if requested */ + if (cfg->cfg & UART_CFG_CTSEV) { + pREGS->INTENSET = UART_INT_CTS; + } + +#ifdef UART_IDLE_FIX + /* REMOVE: if/else block after H/W idle is fixed */ + if (cfg->res > 224) { + pUART->dly = 3072 * (cfg->res - 224); + } + else { + pUART->dly = cfg->res << 2; + } +#endif + + return LPC_OK; +} + +/* EXPORTED API: UART setup special operation like BREAK etc. */ +void UART_SetControl(UART_HANDLE_T hUART, uint32_t cfg) +{ + uint32_t en, dis; + UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS; + + /* Get list of enabled and disabled options */ + en = ((cfg >> 16) & (cfg & 0xFFFF)) << 1; + dis = ((cfg >> 16) & ~(cfg & 0xFFFF)) << 1; + + /* See if it is RX Stop request */ + if (cfg & UART_RX_STOP) { + _UART_StopRx(hUART); + } + + /* See if any IDLEs are enabled */ + if (cfg & (UART_IDLE_MASK << 16)) { + pREGS->INTENSET = (en >> 1) & UART_IDLE_MASK; + pREGS->INTENCLR = (dis >> 1) & UART_IDLE_MASK; + } + + /* See if it is a request BREAK after TX */ + if (en & UART_CTL_TXDIS) { + if (en & UART_CTL_TXBRKEN) { + pREGS->CTL = (pREGS->CTL & ~UART_CTL_RES) | UART_CTL_TXDIS; + while (!(pREGS->STAT & UART_INT_TXDIS)) {} +#ifdef UART_IDLE_FIX + if (1) { + volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly; + while (dly--) {}/* Provide some idling time H/W does not do this */ + } +#endif + } + else { + pREGS->INTENSET = UART_INT_TXDIS; + } + } + + /* See if we are releasing break and resume TX operation */ + if ((dis & UART_CTL_TXDIS) && (dis & UART_CTL_TXBRKEN)) { + pREGS->CTL = pREGS->CTL & ~(UART_CTL_RES | UART_CTL_TXBRKEN); +#ifdef UART_IDLE_FIX + if (1) { + volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly; + while (dly--) {} /* Provide some idling time H/W does not do this */ + } +#endif + } + + /* Check for autobaud and enable autobaud err interrupt */ + if (en & UART_CTL_AUTOBAUD) { + pREGS->INTENSET = UART_INT_ABAUDERR; + } + + pREGS->CTL = ((pREGS->CTL | en) & ~dis) & ~UART_CTL_RES; +} + +/* EXPORTED API: Register a call-back function */ +ErrorCode_t UART_RegisterCB(UART_HANDLE_T hUART, + UART_CBINDEX_T idx, + void (*cb_func)(UART_HANDLE_T, UART_EVENT_T, void *)) +{ + if (idx < UART_CB_RESERVED) { + ((UART_DRIVER_T *) hUART)->cbTable[idx] = cb_func; + } + else { + return ERR_UART_PARAM; + } + + /* Restore internal data handlers when external ones are un-registered */ + if ((idx == UART_CB_DATA) && (cb_func == NULL)) { + ((UART_DRIVER_T *) hUART)->cbTable[idx] = _UART_HandleTxRx; + } + + return LPC_OK; +} + +/* EXPORTED API: UART Event handler */ +void UART_Handler(UART_HANDLE_T hUART) +{ + UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART; + uint32_t flags = pUART->pREGS->INTENSET & pUART->pREGS->INTSTAT; + + if (flags & UART_INT_TXRDY) { + _UART_HandleXfer(pUART, 0); + } + + if (flags & UART_INT_FRMERR) { + pUART->pREGS->STAT = UART_INT_FRMERR; + if (pUART->xfer[1].state == UART_ST_BUSY) { + pUART->xfer[1].state = UART_ST_ERRFRM; + } + _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_FRAME); + } + + if (flags & UART_INT_PARERR) { + pUART->pREGS->STAT = UART_INT_PARERR; + if (pUART->xfer[1].state == UART_ST_BUSY) { + pUART->xfer[1].state = UART_ST_ERRPAR; + } + _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_PARITY); + } + + if (flags & UART_INT_ABAUDERR) { + pUART->pREGS->STAT = UART_INT_ABAUDERR; + if (pUART->xfer[1].state == UART_ST_BUSY) { + pUART->xfer[1].state = UART_ST_ERR; + } + _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_AUTOBAUD); + } + + if (flags & UART_INT_RXNOISE) { + pUART->pREGS->STAT = UART_INT_RXNOISE; + if (pUART->xfer[1].state == UART_ST_BUSY) { + pUART->xfer[1].state = UART_ST_ERRNOISE; + } + _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_RXNOISE); + } + + if (flags & UART_INT_OVR) { + pUART->pREGS->STAT = UART_INT_OVR; + if (pUART->xfer[1].state == UART_ST_BUSY) { + pUART->xfer[1].state = UART_ST_ERROVR; + } + _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_OVERRUN); + } + + if (flags & UART_INT_RXRDY) { + _UART_HandleXfer(pUART, 1); +#ifdef UART_IDLE_FIX + if (1) { + volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly; + while ((pUART->pREGS->STAT & UART_STAT_RXIDLE) && dly--) {} + } +#else + while (pUART->pREGS->STAT & UART_STAT_RXIDLE) {} +#endif + _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_RX_INPROG + ((pUART->pREGS->STAT >> 1) & 1)), &pUART->xfer[1]); + } + + if (flags & UART_INT_TXIDLE) { + _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXIDLE); + } + + if (flags & UART_INT_TXDIS) { + pUART->pREGS->INTENCLR = UART_INT_TXDIS;/* Disable interrupt */ + _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXPAUSED); + } + + if (flags & UART_INT_CTS) { + pUART->pREGS->STAT = UART_INT_CTS; + _UART_InvokeCB(pUART, UART_EV_EVENT, + (void *) ((pUART->pREGS->STAT & UART_STAT_CTS) ? UART_EVENT_CTSHI : UART_EVENT_CTSLO)); + } + + if (flags & UART_INT_BREAK) { + pUART->pREGS->STAT = UART_INT_BREAK | UART_INT_FRMERR; + _UART_InvokeCB(pUART, UART_EV_EVENT, + (void *) ((pUART->pREGS->STAT & UART_STAT_BREAK) ? UART_EVENT_BREAK : UART_EVENT_NOBREAK)); + } + + if (flags & UART_INT_START) { + pUART->pREGS->STAT = UART_INT_START; + _UART_InvokeCB(pUART, UART_RX_START, &pUART->xfer[1]); + } + +} + +/* EXPORTED API: UART Transmit API */ +ErrorCode_t UART_Tx(UART_HANDLE_T hUART, const void *buff, uint16_t len) +{ + return _UART_Xfer((UART_DRIVER_T *) hUART, (void *) buff, len, 0); +} + +/* EXPORTED API: UART Receive API */ +ErrorCode_t UART_Rx(UART_HANDLE_T hUART, void *buff, uint16_t len) +{ + return _UART_Xfer((UART_DRIVER_T *) hUART, buff, len, 1); +} + +/* EXPORTED API: Flush the TX buffer */ +void UART_WaitTX(UART_HANDLE_T hUART) +{ + while (!_UART_HandleXfer(hUART, 0)) {} +} + +/* EXPORTED API: Fetch the data from UART into RX buffer */ +void UART_WaitRX(UART_HANDLE_T hUART) +{ + UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS; + /* See if the data needs to be discarded */ + if (_UART_HandleXfer(hUART, 1) == 2) { + volatile uint32_t dummy; + while ((pREGS->STAT & UART_INT_RXRDY) || !(pREGS->STAT & UART_STAT_RXIDLE)) { + dummy = pREGS->RXDAT; + } + } + while (!_UART_HandleXfer(hUART, 1)) {} +} + +/* EXPORTED API: Function to Get the firmware Version */ +uint32_t UART_GetDriverVersion(void) +{ + return UART_DRIVER_VERSION; +} + +/** + * @brief Table of the addresses of all the UART ROM APIs + * @note This table of function pointers is the API interface. + */ +const ROM_UART_API_T uartrom_api = { + UART_GetMemSize, + UART_CalculateBaud, + UART_Init, + UART_Configure, + UART_SetControl, + UART_RegisterCB, + UART_Handler, + UART_Tx, + UART_Rx, + UART_WaitTX, + UART_WaitRX, + UART_GetDriverVersion, +}; diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..18befb6c851220f04e5c94e2fee5caf28bd2437c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart.h @@ -0,0 +1,107 @@ +/* + * @brief UART ROM API declarations and functions + * + * @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 _HW_UART_H +#define _HW_UART_H + +#define UART_DRIVER_VERSION 0x0100 + +/******************* + * INCLUDE FILES * + ********************/ +#include + +/* UART Status Register bits */ +#define UART_RXRDY (1 << 0) /* Receive data ready */ +#define UART_RXIDLE (1 << 1) /* Receiver Idle */ +#define UART_TXRDY (1 << 2) /* Transmitter ready */ +#define UART_TXIDLE (1 << 3) /* Transmitter Idle */ +#define UART_RXDERR (0xF100) /* overrun err, frame err, parity err, RxNoise err */ +#define UART_TXDERR (0x0200) /* underrun err */ +#define UART_START (0x1000) + +/* UART Interrupt register bits */ +#define UART_INT_RXRDY (1 << 0) +#define UART_INT_TXRDY (1 << 2) +#define UART_INT_TXIDLE (1 << 3) +#define UART_INT_CTS (1 << 5) +#define UART_INT_TXDIS (1 << 6) +#define UART_INT_OVR (1 << 8) +#define UART_INT_BREAK (1 << 11) +#define UART_INT_START (1 << 12) +#define UART_INT_FRMERR (1 << 13) +#define UART_INT_PARERR (1 << 14) +#define UART_INT_RXNOISE (1 << 15) +#define UART_INT_ABAUDERR (1 << 16) + +/* Configuration register bits */ +#define UARTEN 1 + +#define UART_CTL_TXDIS (1UL << 6) +#define UART_CTL_TXBRKEN (1UL << 1) +#define UART_CTL_AUTOBAUD (1UL << 16) +#define UART_CFG_RES (2UL | (1UL << 10) | (1UL << 13) | (1UL << 17) | (0xFFUL << 24)) +#define UART_CFG_ENABLE 1 +#define UART_PAR_MASK (3 << 4) +#define UART_DATA_MASK (3 << 2) +#define UART_CTL_RES (1UL | (7UL << 3) | (1UL << 7) | (0x3FUL << 10) | (0x7FFFUL << 17)) +#define UART_IDLE_MASK (1 << 3) +#define UART_STAT_CTS (1 << 4) +#define UART_STAT_BREAK (1 << 10) +#define UART_STAT_RXIDLE (1 << 1) + +/******************* + * EXPORTED MACROS * + ********************/ +#define ECHO_EN 1 +#define ECHO_DIS 0 + +/********************* + * EXPORTED TYPEDEFS * + **********************/ + +typedef struct { /* UART registers Structure */ + volatile uint32_t CFG; /*!< Offset: 0x000 Configuration register */ + volatile uint32_t CTL; /*!< Offset: 0x004 Control register */ + volatile uint32_t STAT; /*!< Offset: 0x008 Status register */ + volatile uint32_t INTENSET; /*!< Offset: 0x00C Interrupt Enable Read and Set register */ + volatile uint32_t INTENCLR; /*!< Offset: 0x010 Interrupt Enable Clear register */ + const volatile uint32_t RXDAT; /*!< Offset: 0x014 Receiver Data register */ + const volatile uint32_t RXDATSTAT; /*!< Offset: 0x018 Rx Data with status */ + volatile uint32_t TXDAT; /*!< Offset: 0x01C Transmitter Data Register */ + volatile uint32_t BRG; /*!< Offset: 0x020 Baud Rate Generator register */ + const volatile uint32_t INTSTAT; /*!< Offset: 0x024 Interrupt Status register */ + volatile uint32_t OSR; /*!< Offset: 0x028 Oversampling register */ + volatile uint32_t ADR; /*!< Offset: 0x02C Address register (for automatic address matching) */ +} UART_REGS_T; +typedef UART_REGS_T LPC_USART_T; + +#endif /* _HW_UART_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart_rom_api.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..06b1398d4e0a97ea4b56943c29720579a29a543e --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/hw_uart_rom_api.h @@ -0,0 +1,284 @@ +/* + * @brief UART ROM API declarations and functions + * + * @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 __HW_UART_ROM_API_H +#define __HW_UART_ROM_API_H + +#include +#include +#include "error.h" +#include "packing.h" +#include "hw_uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_UART UART/USART ROM driver functions and definitions + * @ingroup ROMAPI_UART_WRAPPER + * @{ + */ + +/** @brief UART Handler type */ +typedef void *UART_HANDLE_T; + +/** @brief UART Data transfer status */ +typedef enum { + UART_ST_DONE, /*!< Transfer completed */ + UART_ST_BUSY, /*!< Transfer is in progress */ + UART_ST_ERR, /*!< Generic error */ + UART_ST_ERRPAR, /*!< ERROR: PARITY */ + UART_ST_ERRFRM, /*!< ERROR: Frame */ + UART_ST_ERRNOISE, /*!< ERROR: Receiver noise */ + UART_ST_ERROVR, /*!< ERROR: Overflow */ +} UART_STATE_T; + +/** @brief UART Transfer structure */ +typedef PRE_PACK struct POST_PACK { + void *buf; /*!< Pointer to buffer */ + uint16_t count; /*!< Number of items to be sent/received [Not number of bytes] */ + uint8_t dwidth; /*!< Width of data items in @a buf; 0 - 8:Bits; 1 - 16:Bits */ +#ifdef UARTROMV2_PRESENT + uint8_t state; /*!< UART TX/RX eror status see #UART_STATE_T */ + uint16_t offset; /*!< Offset of the buffer at which data is being currently processed; usually not used by application */ +#else + volatile uint8_t state; /*!< UART TX/RX eror status see #UART_STATE_T */ + volatile uint16_t offset; /*!< Offset of the buffer at which data is being currently processed; usually not used by application */ +#endif + uint16_t reserved; /*!< Reserved for alignment */ +} UART_DATA_T; + +/** + * @brief UART Baud rate calculation structure + * @note + * Use oversampling (@a ovr) value other than 16, only if the difference + * between the actual baud and desired baud has an unacceptable error percentage. + * Smaller @a ovr values can cause the sampling position within the data-bit + * less accurate an may potentially cause more noise errors or incorrect data + * set ovr to < 10 only when there is no other higher values suitable. + */ +typedef PRE_PACK struct POST_PACK { + uint32_t clk; /*!< IN: Base clock to fractional divider; OUT: "Base clock rate for UART" */ + uint32_t baud; /*!< IN: Required baud rate; OUT: Actual baud rate */ + uint8_t ovr; /*!< IN: Number of desired over samples [0-auto detect or values 5 to 16]; OUT: Auto detected over samples [unchanged if IN is not 0] */ + uint8_t mul; /*!< IN: 0 - calculate MUL, 1 - do't calculate (@a clk) has UART base clock; OUT: MUL value to be set in FRG register */ + uint16_t div; /*!< OUT: Integer divider to divide the "Base clock rate for UART" */ +} UART_BAUD_T; + +/** @brief UART Callback function index + * + * These values must be passed by the application, when they register their + * callbacks with the ROM driver + */ +typedef enum { + UART_CB_START, /*!< UART Callback for TX/RX START event; will have @a event argument set to #UART_TX_START + for TX start event and #UART_RX_START for RX start event */ + UART_CB_DONE, /*!< UART Callback for TX/RX Complete event; will have @a event argument set to #UART_TX_DONE + for TX Done event and #UART_RX_DONE for RX done event*/ + UART_CB_DATA, /*!< UART Callback sending TX data or receiving RX Data; will have @a event argument set + to #UART_TX_DATA for TX data and #UART_RX_DATA for RX data*/ + UART_CB_RXPROG, /*!< UART Callback for every received character (progress); will have @a event argument set + to #UART_RX_INPROG if a character is received and more characters are arriving, + else it will be set to #UART_RX_NOPROG when character is received and no more characters + are found within one character time frame*/ + UART_CB_ERREVT, /*!< UART Callback for any Errors/Events; @a event argument will be #UART_EV_ERROR if the + callback is for error event, or it will be #UART_EV_EVENT if it is nor normal events like + BREAK, TXPAUSE etc., */ + UART_CB_RESERVED/*!< Reserved; Should not be used */ +} UART_CBINDEX_T; + +/** @brief UART Event enumerations + * + * These values are passed by the driver as the second argument + * of the callback functions that are invoked by the ROM driver + */ +typedef enum { + UART_TX_START, /*!< UART TX Start event; @a arg will be a pointer to #UART_DATA_T that has information related to TX buffer */ + UART_RX_START, /*!< UART RX Start event; @a arg will be a pointer to #UART_DATA_T that has information related to RX buffer + this event does not mean a start of RX into the given buffer, instead it means receiver has started receiving + new character after being idle for one character frame time */ + UART_TX_DONE, /*!< UART TX Complete event; @a arg will be a pointer to #UART_DATA_T that has information related to TX Buffer */ + UART_RX_DONE, /*!< UART RX Complete event; @a arg will be a pointer to #UART_DATA_T that has information related to RX Buffer */ + UART_TX_DATA, /*!< UART Push TX data; @a arg will be pointer to #UART_DATA_T; @a buf will contain the pointer to the data + to be sent, @a sz will have the number of items to be sent and @a b16 will be set to 1 if the data to be + transmitted is of 16-bits wide (else @a b16 will be 0); after pushing the data from buf the callback should + set the @a sz to number of bytes remaining to be sent */ + UART_RX_DATA, /*!< UART Pop RX data; @a arg will be pointer to #UART_DATA_T; @a buf will contain the pointer to memory where + receive data be stored, @a sz will have the number of items to be received and @a b16 will be set to 1 if the + data to be received is of 16-bits wide [Bits 9 to 15 must be 0] (else @a b16 will be 0); after reading the data + into buf the callback should set the @a sz to number of bytes yet to be received */ + UART_RX_INPROG, /*!< Received a UART character and more characters are being processed by shift register */ + UART_RX_NOPROG, /*!< Received a UART character and no more characters are received within one character time */ + UART_EV_ERROR, /*!< UART Error; @a arg parameter will be one of the UART_ERROR_XXX (Example #UART_ERROR_FRAME) */ + UART_EV_EVENT /*!< UART special events; @a arg parameter will be one of the UART_EVENT_XXX (Example #UART_EVENT_BREAK) */ +} UART_EVENT_T; + +/** @brief UART Configuration bits + * + * These bits can be OR'd to get the configuration value (second parameter) for aConfigure API + */ +#undef UART_CFG_MODE32K +#undef UART_CFG_LINMODE +#define UART_CFG_7BIT 0 /*!< UART uses 7-Bit data transfer; Buffer used by Send and Receive API must be of type uint8_t * */ +#define UART_CFG_8BIT (1 << 2) /*!< UART uses 8-Bit data transfer; Buffer used by Send and Receive API must be of type uint8_t * */ +#define UART_CFG_9BIT (1 << 3) /*!< UART uses 9-Bit data transfer; Buffer used by Send and Receive API must be of type uint16_t * */ +#define UART_CFG_NOPAR 0 /*!< UART Transfers do not use parity */ +#define UART_CFG_EVENPAR (2 << 5) /*!< Enable EVEN Parity */ +#define UART_CFG_ODDPAR (3 << 4) /*!< Enable ODD Parity */ +#define UART_CFG_1STOP 0 /*!< UART Tx/Rx will use 1-stop bit at the end of transfer */ +#define UART_CFG_2STOP (1 << 6) /*!< UART Tx/Rx will use 2-Stop bits towards end of transfers */ +#define UART_CFG_MODE32K (1 << 7) /*!< Use 32KHz RTC clock; Needs special clocking setup to be done by the application */ +#define UART_CFG_LINMODE (1 << 8) /*!< Break detect and generation will use LIN bus operation */ +#define UART_CFG_HWFLOW (1 << 9) /*!< Enable Hardware flow control */ +#define UART_CFG_CTSEV (1 << 10) /*!< Enable CTS events */ +#define UART_CFG_BRKRX (1 << 13) /*!< Enable BREAK receive events */ + +/* USART Synchorous mode configurations */ +#define UART_CFG_SYNMODE (1 << 11)/*!< Synchronous Mode: Enable Synchronous mode */ +#define UART_CFG_FALLING 0 /*!< Synchronous Mode: Sample data during falling edge of SCLK (Must be used with #UART_CFG_SYNMODE) */ +#define UART_CFG_RISING (1 << 12)/*!< Synchronous mode: Sample data during rising edge of SCLK (Must be used with #UART_CFG_SYNMODE) */ +#define UART_CFG_MASTER (1 << 14)/*!< Synchronous mode: USART will be the master (Must be used with #UART_CFG_SYNMODE) */ + +/* UART Modes */ +#define UART_CFG_LOOPBACK (1 << 15)/*!< UART will operate in diagnostic loopback mode */ +#define UART_CFG_IRDAMODE (1 << 16)/*!< UART will operate in IrDA mode */ + +/* RS-485 specific configurations */ +#define UART_CFG_OESEL (1 << 20)/*!< RS-485: RTS will be used to control output enable of an RS-485 transceiver */ +#define UART_CFG_OETA (1 << 18)/*!< RS-485: Deassertion of Output Enable signal will be delayed for 1 character time; should be used with #UART_CFG_OESEL */ +#define UART_CFG_AUTOADDR (1 << 19)/*!< RS-485: Enable Automatic address checking [If MSB of Rx data is 1, hadware compares it with address set with #UART_CFG_ADDR] */ +#define UART_CFG_OEPOLHIGH (1 << 21)/*!< RS-485: Output enable signal is active high */ +#define UART_CFG_ADDR(adr) ((adr) << 24)/*!< RS-485: Set RS-485 device address comparision */ + +#define UART_CFG_RXPOL (1 << 22)/*!< Invert the RX Pin polarity; 1 considered start and 0 considered stop, with inverted data */ +#define UART_CFG_TXPOL (1 << 23)/*!< Invert the TX Pin polarity; 1 sent as start and 0 sent as stop, with inverted data */ + +/** @brief UART configuration options used with UART_SetCtrl() */ +#define UART_BREAK_ON ((1UL << 0) | (1UL << 16)) /*!< Sends BREAK on the TX line till SetConfig() called with #UART_BREAK_OFF; + Sending BREAK when TX is in progress might make the receiver get a frame error + Use UART_TX_PAUSE before setting UART_BREAK_ON to safely send break */ +#define UART_BREAK_OFF (1UL << 16) /*!< Turns OFF break condition */ +#define UART_ADDRDET_ON ((1UL << 1) | (1UL << 17)) /*!< Enable Address detect mode in RS-485; When turned on receiver ignores all + incoming data that has MSB [Typically 9th Bit] as 0, when data with MSB as 1 + is received it will cause the UART TX EVENT, software can compare the address + and call SetConfig with #UART_ADDRDET_OFF to resume to normal mode */ +#define UART_ADDRDET_OFF (1UL << 17) /*!< Disable address detect mode in RS-485 */ +#define UART_TX_PAUSE ((1UL << 5) | (1UL << 21)) /*!< Pause Transmit; typically used for Software flow control implementation this, + will invoke callback registerd for #UART_CB_ERREVT with @a event as #UART_EV_EVENT + and the (void *) arg will be #UART_EVENT_TXPAUSED, the callback will be called after + the current data in shift register is completely transmitted */ +#define UART_TX_RESUME (1UL << 21) /*!< Resume Transmit; typically used for Software flow control */ +#define UART_CCLK_ON ((1UL << 7) | (1UL << 23)) /*!< In Sync mode; sends continuous clock so that RX can happen independent of TX */ +#define UART_CCLK_OFF (1UL << 23) /*!< In Sync mode; Disables continuous clock so that clock will be generated only when characters are being sent */ +#define UART_CCLK_AUTO ((1UL << 8) | (1UL << 24)) /*!< In Sync mode; Sends continuous clock until a complete character is received */ +#define UART_AUTOBAUD ((1UL << 15) | (1UL << 31)) /*!< Enables Autobaud mode; sets the DIV value based on received character */ +#define UART_TXIDLE_ON ((1UL << 3) | (1UL << 19)) /*!< Enable event generation on TX IDLE */ +#define UART_TXIDLE_OFF (1UL << 19) /*!< Disable event generation on TX IDLE */ +#define UART_RX_STOP (1UL << 18) + +/* @brief UART event codes for arg parameter of callback (see #UART_EV_EVENT) */ +#define UART_EVENT_BREAK 0x100 /*!< UART RX line is in BREAK state */ +#define UART_EVENT_NOBREAK 0x101 /*!< UART RX line restored from BREAK state */ +#define UART_EVENT_TXIDLE 0x102 /*!< UART TX is idle; nothing in shift register */ +#define UART_EVENT_TXPAUSED 0x103 /*!< TX is paused */ +#define UART_EVENT_CTSHI 0x104 /*!< CTS line went from low to high; typically used for flow-control */ +#define UART_EVENT_CTSLO 0x105 /*!< CTS line went from High to Low; typically used for flow-control */ + +/** @brief Error codes for arg parameter of callback (see #UART_EV_ERROR) */ +#define UART_ERROR_FRAME 0x200 /*!< UART Frame error */ +#define UART_ERROR_PARITY 0x201 /*!< UART Parity error */ +#define UART_ERROR_AUTOBAUD 0x202 /*!< UART Autobaud error */ +#define UART_ERROR_RXNOISE 0x203 /*!< UART RX NOISE error */ +#define UART_ERROR_OVERRUN 0x204 /*!< UART RX overrun error */ + +/** @brief User context conversion macro + * Macro used to extract the user defined data pointer from a UART ROM + * driver handle.
+ * To get a user context, simply use the macro on the driver's handle: + * void *pUserData = ROM_UART_HANDLE_TOUDATA(hUART); + */ +#define ROM_UART_HANDLE_TOUDATA(p) (void *) (*(uint32_t *) p) + +/** @brief UART Configuration data structure */ +typedef PRE_PACK struct POST_PACK { + uint32_t cfg; /*!< UART Configuration value; OR'ed UART_CFG_XXXX values(example #UART_CFG_8BIT) */ + uint16_t div; /*!< UART baudrate divider value; usually calculated by using UART_CalBaud() API */ + uint8_t ovr; /*!< UART Over sampling value; usually calculated by using UART_CalBaud() API */ + uint8_t res; /*!< Reserved for alignment; must be 0 */ +} UART_CFG_T; + +/** + * @brief Structure that has the API pointers in ROM Table + */ +typedef PRE_PACK struct POST_PACK { + /* Index of All the UART/USART driver APIs */ + uint32_t (*GetMemSize)(void); /*!< Returns needed memory size required for run-time context of UART driver */ + ErrorCode_t (*CalBaud)(UART_BAUD_T *baud); /*!< Calculates the baudrate parameters for the given frequency, baud rate */ + UART_HANDLE_T (*Init)(void *pMem, uint32_t baseAddr, void *pUserData); /*!< Initializes the UART driver and peripheral */ + ErrorCode_t (*Configure)(UART_HANDLE_T hUART, const UART_CFG_T *cfg); /*!< Configure the UART to given parameters */ + void (*SetCtrl)(UART_HANDLE_T hUART, uint32_t cfgVal); /*!< Set/Clear special control operations like BREAK, IDLE, etc., */ + ErrorCode_t (*RegisterCB)(UART_HANDLE_T hUART, UART_CBINDEX_T cbIndex, + void (*pCbFunc)(UART_HANDLE_T, UART_EVENT_T, void *)); /*!< Registers an UART callback function */ + void (*Handler)(UART_HANDLE_T hUART); /*!< UART Event handler, should be called from the ISR */ + ErrorCode_t (*Send)(UART_HANDLE_T hUART, const void *buffer, uint16_t size);/*!< Send data to UART */ + ErrorCode_t (*Receive)(UART_HANDLE_T hUART, void *buffer, uint16_t size); /*!< Receive data from UART */ + void (*WaitTx)(UART_HANDLE_T hUART);/*!< Wait for UART TX to complete; Used for polling */ + void (*WaitRx)(UART_HANDLE_T hUART);/*!< Wait for UART data receive to complete; Used for polling */ + uint32_t (*GetDriverVersion)(void); /*!< Get the version of the Driver Firmware in ROM */ +} ROM_UART_API_T; + +/* UART Register offsets */ +#define UART_TX_OFFSET 0x1C +#define UART_RX_OFFSET 0x14 + +/** @brief Calculates UART TX register base address from UART handle */ +#define UART_DMA_TXADDR(han) (*(((uint32_t *) (han)) + 1) + UART_TX_OFFSET) + +/** @brief Calculates UART RX register base address from UART handle */ +#define UART_DMA_RXADDR(han) (*(((uint32_t *) (han)) + 1) + UART_RX_OFFSET) + +/* REMOVE: after H/W IDLE is fixed */ +#define UART_BIT_DLY(baud) ((baud) / 4800 ? 921600 / (baud) : 2400 / (baud) + 224) + +/* Extern declaration so that application can access + * pointer to the function table + */ +extern const ROM_UART_API_T uartrom_api; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __HW_UART_ROM_API_H */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/inmux_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/inmux_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..5347f055f0a01b2142a849a0edf98af5bea17ccc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/inmux_5410x.h @@ -0,0 +1,162 @@ +/* + * @brief LPC5410X Input Mux Registers and 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 __INMUX_5410X_H_ +#define __INMUX_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup INMUX_5410X CHIP: LPC5410X Input Mux Registers and Driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X Input Mux Register Block Structure + */ +typedef struct { /*!< INMUX Structure */ + __IO uint32_t RESERVED0[6]; + __I uint32_t RESERVED1[42]; + __IO uint32_t PINTSEL[8]; /*!< Pin interrupt select registers */ + __IO uint32_t DMA_ITRIG_INMUX[22]; /*!< Input mux register for DMA trigger inputs */ + __I uint32_t RESERVED2[2]; + __IO uint32_t DMA_OTRIG_INMUX[4]; /*!< Input mux register for DMA trigger inputs */ + __I uint32_t RESERVED3[4]; + __IO uint32_t FREQMEAS_REF; /*!< Clock selection for frequency measurement ref clock */ + __IO uint32_t FREQMEAS_TARGET; /*!< Clock selection for frequency measurement target clock */ +} LPC_INMUX_T; + +/** + * @brief GPIO Pin Interrupt Pin Select (sets PINTSEL register) + * @param pintSel : GPIO PINTSEL interrupt, should be: 0 to 7 + * @param portNum : GPIO port number interrupt, should be: 0 to 1 + * @param pinNum : GPIO pin number Interrupt, should be: 0 to 31 + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_PinIntSel(uint8_t pintSel, uint8_t portNum, uint8_t pinNum) +{ + LPC_INMUX->PINTSEL[pintSel] = (portNum * 32) + pinNum; +} + +/* DMA triggers that can mapped to DMA channels */ +typedef enum { + DMATRIG_ADC0_SEQA_IRQ = 0, /*!< ADC0 sequencer A interrupt as trigger */ + DMATRIG_ADC0_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_TIMER0_MATCH0, /*!< Timer 0, match 0 trigger */ + DMATRIG_TIMER0_MATCH1, /*!< Timer 0, match 1 trigger */ + DMATRIG_TIMER1_MATCH0, /*!< Timer 1, match 0 trigger */ + DMATRIG_TIMER1_MATCH1, /*!< Timer 1, match 1 trigger */ + DMATRIG_TIMER2_MATCH0, /*!< Timer 2, match 0 trigger */ + DMATRIG_TIMER2_MATCH1, /*!< Timer 2, match 1 trigger */ + DMATRIG_TIMER3_MATCH0, /*!< Timer 3, match 0 trigger */ + DMATRIG_TIMER3_MATCH1, /*!< Timer 3, match 1 trigger */ + DMATRIG_TIMER4_MATCH0, /*!< Timer 4, match 0 trigger */ + DMATRIG_TIMER4_MATCH1, /*!< Timer 4, match 1 trigger */ + DMATRIG_PININT0, /*!< Pin interrupt 0 trigger */ + DMATRIG_PININT1, /*!< Pin interrupt 1 trigger */ + DMATRIG_PININT2, /*!< Pin interrupt 2 trigger */ + DMATRIG_PININT3, /*!< Pin interrupt 3 trigger */ + DMATRIG_OUTMUX0, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX1, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX2, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX3 /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ +} DMA_TRIGSRC_T; + +/** + * @brief Select a trigger source for a DMA channel + * @param ch : DMA channel number + * @param trig : Trigger source for the DMA channel + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetDMATrigger(uint8_t ch, DMA_TRIGSRC_T trig) +{ + LPC_INMUX->DMA_ITRIG_INMUX[ch] = (uint32_t) trig; +} + +/** + * @brief Selects a DMA trigger source for the DMATRIG_OUTMUXn IDs + * @param index : Select 0 to 3 to sets the source for DMATRIG_OUTMUX0 to DMATRIG_OUTMUX3 + * @param dmaCh : DMA channel to select for DMATRIG_OUTMUXn source + * @return Nothing + * @note This function sets the DMA trigger (out) source used with the DMATRIG_OUTMUXn + * trigger source. + */ +STATIC INLINE void Chip_INMUX_SetDMAOutMux(uint8_t index, uint8_t dmaCh) +{ + LPC_INMUX->DMA_OTRIG_INMUX[index] = (uint32_t) dmaCh; +} + +/* Freqeuency measure reference and target clock sources */ +typedef enum { + FREQMSR_CLKIN = 0, /*!< CLKIN pin */ + FREQMSR_IRC, /*!< Internal RC (IRC) oscillator */ + FREQMSR_WDOSC, /*!< Watchdog oscillator */ + FREQMSR_32KHZOSC, /*!< 32KHz (RTC) oscillator rate */ + FREQ_MEAS_MAIN_CLK, /*!< main system clock */ + FREQMSR_PIO0_4, /*!< External pin PIO0_4 as input rate */ + FREQMSR_PIO0_20, /*!< External pin PIO0_20 as input rate */ + FREQMSR_PIO0_24, /*!< External pin PIO0_24 as input rate */ + FREQMSR_PIO1_4 /*!< External pin PIO1_4 as input rate */ +} FREQMSR_SRC_T; + +/** + * @brief Selects a reference clock used with the frequency measure function + * @param ref : Frequency measure function reference clock + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetFreqMeasRefClock(FREQMSR_SRC_T ref) +{ + LPC_INMUX->FREQMEAS_REF = (uint32_t) ref; +} + +/** + * @brief Selects a target clock used with the frequency measure function + * @param targ : Frequency measure function reference clock + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetFreqMeasTargClock(FREQMSR_SRC_T targ) +{ + LPC_INMUX->FREQMEAS_TARGET = (uint32_t) targ; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __INMUX_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..865279a7888868817c3be0ef00f94ad9369a034d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.c @@ -0,0 +1,58 @@ +/* + * @brief LPC5410X IOCON 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* 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].port, pinArray[ix].pin, pinArray[ix].modefunc); + } +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..2ae340b5c9ec0aa2171a4b5474e3609784d02bfc --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/iocon_5410x.h @@ -0,0 +1,139 @@ +/* + * @brief LPC5410X IOCON register block and 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 __IOCON_5410X_H_ +#define __IOCON_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup IOCON_5410X CHIP: LPC5410X IOCON register block and driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X IO Configuration Unit register block structure + */ +typedef struct { /*!< LPC5410X IOCON Structure */ + __IO uint32_t PIO[2][32]; +} LPC_IOCON_T; + +/** + * @brief Array of IOCON pin definitions passed to Chip_IOCON_SetPinMuxing() must be in this format + */ +typedef struct { + uint32_t port : 8; /* Pin port */ + uint32_t pin : 8; /* Pin number */ + uint32_t modefunc : 16; /* Function and mode */ +} PINMUX_GRP_T; + +/** + * IOCON function and mode selection definitions + * See the User Manual for specific modes and functions supported by the + * various LPC15XX pins. + */ +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */ +#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */ +#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */ +#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */ +#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */ +#define IOCON_MODE_INACT (0x0 << 3) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << 3) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << 3) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << 3) /*!< Selects pin repeater function */ +#define IOCON_HYS_EN (0x1 << 5) /*!< Enables hysteresis */ +#define IOCON_GPIO_MODE (0x1 << 5) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x1 << 5) /*!< I2C Slew Rate Control */ +#define IOCON_INV_EN (0x1 << 6) /*!< Enables invert function on input */ +#define IOCON_ANALOG_EN (0x0 << 7) /*!< Enables analog function by setting 0 to bit 7 */ +#define IOCON_DIGITAL_EN (0x1 << 7) /*!< Enables digital function by setting 1 to bit 7(default) */ +#define IOCON_STDI2C_EN (0x1 << 8) /*!< I2C standard mode/fast-mode */ +#define IOCON_FASTI2C_EN (0x3 << 8) /*!< I2C Fast-mode Plus and high-speed slave */ +#define IOCON_INPFILT_OFF (0x1 << 8) /*!< Input filter Off for GPIO pins */ +#define IOCON_INPFILT_ON (0x0 << 8) /*!< Input filter On for GPIO pins */ +#define IOCON_OPENDRAIN_EN (0x1 << 10) /*!< Enables open-drain function */ +#define IOCON_S_MODE_0CLK (0x0 << 11) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK (0x1 << 11) /*!< Input pulses shorter than 1 filter clock are rejected */ +#define IOCON_S_MODE_2CLK (0x2 << 11) /*!< Input pulses shorter than 2 filter clock2 are rejected */ +#define IOCON_S_MODE_3CLK (0x3 << 11) /*!< Input pulses shorter than 3 filter clock2 are rejected */ +#define IOCON_S_MODE(clks) ((clks) << 11) /*!< Select clocks for digital input filter mode */ +#define IOCON_CLKDIV(div) ((div) << 13) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ + +/** + * @brief Sets I/O Control pin mux + * @param pIOCON : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @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 port, uint8_t pin, uint32_t modefunc) +{ + pIOCON->PIO[port][pin] = modefunc; +} + +/** + * @brief I/O Control pin mux + * @param pIOCON : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @param pin : GPIO pin to mux + * @param mode : OR'ed values or type IOCON_* + * @param func : Pin function, value of type IOCON_FUNC? + * @return Nothing + */ +STATIC INLINE void Chip_IOCON_PinMux(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin, uint16_t mode, uint8_t func) +{ + Chip_IOCON_PinMuxSet(pIOCON, port, pin, (uint32_t) (mode | func)); +} + +/** + * @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); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __IOCON_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/keil_output/core_m4/ArInp.Scr b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/keil_output/core_m4/ArInp.Scr new file mode 100644 index 0000000000000000000000000000000000000000..599fc03c973c9ce31e36f1b3869825381a7a98ea --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/keil_output/core_m4/ArInp.Scr @@ -0,0 +1,47 @@ +--create .\keil_output\core_m4\lib_chip_5410x.lib +.\keil_output\core_m4\ring_buffer.o +.\keil_output\core_m4\chip_5410x.o +.\keil_output\core_m4\clock_5410x.o +.\keil_output\core_m4\crc_5410x.o +.\keil_output\core_m4\gpio_5410x.o +.\keil_output\core_m4\iocon_5410x.o +.\keil_output\core_m4\pinint_5410x.o +.\keil_output\core_m4\sct_5410x.o +.\keil_output\core_m4\sct_pwm_5410x.o +.\keil_output\core_m4\syscon_5410x.o +.\keil_output\core_m4\sysinit_5410x.o +.\keil_output\core_m4\timer_5410x.o +.\keil_output\core_m4\utick_5410x.o +.\keil_output\core_m4\wwdt_5410x.o +.\keil_output\core_m4\rtc_5410x.o +.\keil_output\core_m4\fpu_init.o +.\keil_output\core_m4\iap.o +.\keil_output\core_m4\gpiogroup_5410x.o +.\keil_output\core_m4\stopwatch_5410x.o +.\keil_output\core_m4\ritimer_5410x.o +.\keil_output\core_m4\romapi_adc.o +.\keil_output\core_m4\romapi_dma.o +.\keil_output\core_m4\romapi_i2cm.o +.\keil_output\core_m4\romapi_i2cmon.o +.\keil_output\core_m4\romapi_i2cs.o +.\keil_output\core_m4\romapi_spim.o +.\keil_output\core_m4\romapi_spis.o +.\keil_output\core_m4\romapi_uart.o +.\keil_output\core_m4\rtc_ut.o +.\keil_output\core_m4\pll_5410x.o +.\keil_output\core_m4\hw_adc.o +.\keil_output\core_m4\hw_dmaaltd.o +.\keil_output\core_m4\hw_dmaaltd_rom_api.o +.\keil_output\core_m4\hw_i2cmd.o +.\keil_output\core_m4\hw_i2cmd_rom_api.o +.\keil_output\core_m4\hw_i2cmond.o +.\keil_output\core_m4\hw_i2cmond_rom_api.o +.\keil_output\core_m4\hw_i2csd.o +.\keil_output\core_m4\hw_i2csd_rom_api.o +.\keil_output\core_m4\hw_spimd_rom_api.o +.\keil_output\core_m4\hw_spisd.o +.\keil_output\core_m4\hw_spisd_rom_api.o +.\keil_output\core_m4\hw_spimd.o +.\keil_output\core_m4\hw_uart.o +.\keil_output\core_m4\fifo_5410x.o +.\power_lib\keil\lib_power.lib diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.ewp b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.ewp new file mode 100644 index 0000000000000000000000000000000000000000..61b8390d91d712d443fbe456872998aa325d0d78 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.ewp @@ -0,0 +1,1095 @@ + + + + 2 + + chip_5410x_lib + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + csp + + $PROJ_DIR$\chip_5410x.c + + + $PROJ_DIR$\clock_5410x.c + + + $PROJ_DIR$\crc_5410x.c + + + $PROJ_DIR$\fifo_5410x.c + + + $PROJ_DIR$\..\chip_common\fpu_init.c + + + $PROJ_DIR$\gpio_5410x.c + + + $PROJ_DIR$\gpiogroup_5410x.c + + + $PROJ_DIR$\hw_adc.c + + + $PROJ_DIR$\hw_dmaaltd.c + + + $PROJ_DIR$\hw_dmaaltd_rom_api.c + + + $PROJ_DIR$\hw_i2cmd.c + + + $PROJ_DIR$\hw_i2cmd_rom_api.c + + + $PROJ_DIR$\hw_i2cmond.c + + + $PROJ_DIR$\hw_i2cmond_rom_api.c + + + $PROJ_DIR$\hw_i2csd.c + + + $PROJ_DIR$\hw_i2csd_rom_api.c + + + $PROJ_DIR$\hw_spimd.c + + + $PROJ_DIR$\hw_spimd_rom_api.c + + + $PROJ_DIR$\hw_spisd.c + + + $PROJ_DIR$\hw_spisd_rom_api.c + + + $PROJ_DIR$\hw_uart.c + + + $PROJ_DIR$\..\chip_common\iap.c + + + $PROJ_DIR$\iocon_5410x.c + + + $PROJ_DIR$\pinint_5410x.c + + + $PROJ_DIR$\pll_5410x.c + + + $PROJ_DIR$\..\chip_common\ring_buffer.c + + + $PROJ_DIR$\ritimer_5410x.c + + + $PROJ_DIR$\romapi_adc.c + + + $PROJ_DIR$\romapi_dma.c + + + $PROJ_DIR$\romapi_i2cm.c + + + $PROJ_DIR$\romapi_i2cmon.c + + + $PROJ_DIR$\romapi_i2cs.c + + + $PROJ_DIR$\romapi_spim.c + + + $PROJ_DIR$\romapi_spis.c + + + $PROJ_DIR$\romapi_uart.c + + + $PROJ_DIR$\rtc_5410x.c + + + $PROJ_DIR$\..\chip_common\rtc_ut.c + + + $PROJ_DIR$\sct_5410x.c + + + $PROJ_DIR$\sct_pwm_5410x.c + + + $PROJ_DIR$\stopwatch_5410x.c + + + $PROJ_DIR$\syscon_5410x.c + + + $PROJ_DIR$\sysinit_5410x.c + + + $PROJ_DIR$\timer_5410x.c + + + $PROJ_DIR$\utick_5410x.c + + + $PROJ_DIR$\wwdt_5410x.c + + + + libs + + $PROJ_DIR$\power_lib\iar\lib_power.a + + + + + diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvoptx b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvoptx new file mode 100644 index 0000000000000000000000000000000000000000..2c9d1a08c86412939782241367b33701ff666907 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvoptx @@ -0,0 +1,794 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + lib_chip_5410x + 0x4 + ARM-ADS + + 12000000 + + 0 + 1 + 0 + 1 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\keil_output\core_m4\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 8 + + + 0 + LPC812 LPCXpresso Board (LPC54xxx LPCXpresso) + http://www.nxp.com/demoboard/OM13053.html + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + + + + + + + + + + + BIN\UL2CM3.DLL + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + + + + + 0 + 0 + 67 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + E:\RT_Internship_ready\TestTransplant\rt-thread\rt-thread\bsp\examples\periph\blinky\blinky.c + + +
+
+ + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + +
+
+ + + csp + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + 0 + ..\chip_common\ring_buffer.c + ring_buffer.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + 0 + .\chip_5410x.c + chip_5410x.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + 0 + .\clock_5410x.c + clock_5410x.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + 0 + .\crc_5410x.c + crc_5410x.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + 0 + .\gpio_5410x.c + gpio_5410x.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + 0 + .\iocon_5410x.c + iocon_5410x.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + 0 + .\pinint_5410x.c + pinint_5410x.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + 0 + .\sct_5410x.c + sct_5410x.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + 0 + .\sct_pwm_5410x.c + sct_pwm_5410x.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + 0 + .\syscon_5410x.c + syscon_5410x.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + 0 + .\sysinit_5410x.c + sysinit_5410x.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + 0 + .\timer_5410x.c + timer_5410x.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + 0 + .\utick_5410x.c + utick_5410x.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + 0 + .\wwdt_5410x.c + wwdt_5410x.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + 0 + .\rtc_5410x.c + rtc_5410x.c + 0 + 0 + + + 1 + 16 + 1 + 0 + 0 + 0 + 0 + ..\chip_common\fpu_init.c + fpu_init.c + 0 + 0 + + + 1 + 17 + 1 + 0 + 0 + 0 + 0 + ..\chip_common\iap.c + iap.c + 0 + 0 + + + 1 + 18 + 1 + 0 + 0 + 0 + 0 + .\gpiogroup_5410x.c + gpiogroup_5410x.c + 0 + 0 + + + 1 + 19 + 1 + 0 + 0 + 0 + 0 + .\stopwatch_5410x.c + stopwatch_5410x.c + 0 + 0 + + + 1 + 20 + 1 + 0 + 0 + 0 + 0 + .\ritimer_5410x.c + ritimer_5410x.c + 0 + 0 + + + 1 + 21 + 1 + 0 + 0 + 0 + 0 + .\romapi_adc.c + romapi_adc.c + 0 + 0 + + + 1 + 22 + 1 + 0 + 0 + 0 + 0 + .\romapi_dma.c + romapi_dma.c + 0 + 0 + + + 1 + 23 + 1 + 0 + 0 + 0 + 0 + .\romapi_i2cm.c + romapi_i2cm.c + 0 + 0 + + + 1 + 24 + 1 + 0 + 0 + 0 + 0 + .\romapi_i2cmon.c + romapi_i2cmon.c + 0 + 0 + + + 1 + 25 + 1 + 0 + 0 + 0 + 0 + .\romapi_i2cs.c + romapi_i2cs.c + 0 + 0 + + + 1 + 26 + 1 + 0 + 0 + 0 + 0 + .\romapi_spim.c + romapi_spim.c + 0 + 0 + + + 1 + 27 + 1 + 0 + 0 + 0 + 0 + .\romapi_spis.c + romapi_spis.c + 0 + 0 + + + 1 + 28 + 1 + 0 + 0 + 0 + 0 + .\romapi_uart.c + romapi_uart.c + 0 + 0 + + + 1 + 29 + 1 + 0 + 0 + 0 + 0 + ..\chip_common\rtc_ut.c + rtc_ut.c + 0 + 0 + + + 1 + 30 + 1 + 0 + 0 + 0 + 0 + .\pll_5410x.c + pll_5410x.c + 0 + 0 + + + 1 + 31 + 1 + 0 + 0 + 0 + 0 + .\hw_adc.c + hw_adc.c + 0 + 0 + + + 1 + 32 + 1 + 0 + 0 + 0 + 0 + .\hw_dmaaltd.c + hw_dmaaltd.c + 0 + 0 + + + 1 + 33 + 1 + 0 + 0 + 0 + 0 + .\hw_dmaaltd_rom_api.c + hw_dmaaltd_rom_api.c + 0 + 0 + + + 1 + 34 + 1 + 0 + 0 + 0 + 0 + .\hw_i2cmd.c + hw_i2cmd.c + 0 + 0 + + + 1 + 35 + 1 + 0 + 0 + 0 + 0 + .\hw_i2cmd_rom_api.c + hw_i2cmd_rom_api.c + 0 + 0 + + + 1 + 36 + 1 + 0 + 0 + 0 + 0 + .\hw_i2cmond.c + hw_i2cmond.c + 0 + 0 + + + 1 + 37 + 1 + 0 + 0 + 0 + 0 + .\hw_i2cmond_rom_api.c + hw_i2cmond_rom_api.c + 0 + 0 + + + 1 + 38 + 1 + 0 + 0 + 0 + 0 + .\hw_i2csd.c + hw_i2csd.c + 0 + 0 + + + 1 + 39 + 1 + 0 + 0 + 0 + 0 + .\hw_i2csd_rom_api.c + hw_i2csd_rom_api.c + 0 + 0 + + + 1 + 40 + 1 + 0 + 0 + 0 + 0 + .\hw_spimd_rom_api.c + hw_spimd_rom_api.c + 0 + 0 + + + 1 + 41 + 1 + 0 + 0 + 0 + 0 + .\hw_spisd.c + hw_spisd.c + 0 + 0 + + + 1 + 42 + 1 + 0 + 0 + 0 + 0 + .\hw_spisd_rom_api.c + hw_spisd_rom_api.c + 0 + 0 + + + 1 + 43 + 1 + 0 + 0 + 0 + 0 + .\hw_spimd.c + hw_spimd.c + 0 + 0 + + + 1 + 44 + 1 + 0 + 0 + 0 + 0 + .\hw_uart.c + hw_uart.c + 0 + 0 + + + 1 + 45 + 1 + 0 + 0 + 0 + 0 + .\fifo_5410x.c + fifo_5410x.c + 0 + 0 + + + + + lib + 1 + 0 + 0 + 0 + + 2 + 46 + 4 + 0 + 0 + 0 + 0 + .\power_lib\keil\lib_power.lib + lib_power.lib + 0 + 0 + + + +
diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvprojx b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..92f93403c2687be7abb462599143a703304dca4e --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x.uvprojx @@ -0,0 +1,652 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + lib_chip_5410x + 0x4 + ARM-ADS + + + LPC54102:M4 + NXP + Keil.LPC54000_DFP.1.0.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x02000000,0x10000) IRAM2(0x02010000,0x08000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + 0 + $$Device:LPC54102$Device\Include\LPC54xxx.h + + + + + + + + + + $$Device:LPC54102$SVD\LPC54xxx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\keil_output\core_m4\ + lib_chip_5410x + 0 + 1 + 0 + 1 + 1 + .\keil_output\core_m4\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + + 0 + 1 + + + + + + + + + + + + + + BIN\UL2CM3.DLL + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 0 + 0x2010000 + 0x8000 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + + + CORE_M4 + + .\config;..\chip_5410x;..\chip_common;..\..\..\CMSIS\CMSIS\Include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x00000000 + + + + + + + + + + + + + csp + + + ring_buffer.c + 1 + ..\chip_common\ring_buffer.c + + + chip_5410x.c + 1 + .\chip_5410x.c + + + clock_5410x.c + 1 + .\clock_5410x.c + + + crc_5410x.c + 1 + .\crc_5410x.c + + + gpio_5410x.c + 1 + .\gpio_5410x.c + + + iocon_5410x.c + 1 + .\iocon_5410x.c + + + pinint_5410x.c + 1 + .\pinint_5410x.c + + + sct_5410x.c + 1 + .\sct_5410x.c + + + sct_pwm_5410x.c + 1 + .\sct_pwm_5410x.c + + + syscon_5410x.c + 1 + .\syscon_5410x.c + + + sysinit_5410x.c + 1 + .\sysinit_5410x.c + + + timer_5410x.c + 1 + .\timer_5410x.c + + + utick_5410x.c + 1 + .\utick_5410x.c + + + wwdt_5410x.c + 1 + .\wwdt_5410x.c + + + rtc_5410x.c + 1 + .\rtc_5410x.c + + + fpu_init.c + 1 + ..\chip_common\fpu_init.c + + + iap.c + 1 + ..\chip_common\iap.c + + + gpiogroup_5410x.c + 1 + .\gpiogroup_5410x.c + + + stopwatch_5410x.c + 1 + .\stopwatch_5410x.c + + + ritimer_5410x.c + 1 + .\ritimer_5410x.c + + + romapi_adc.c + 1 + .\romapi_adc.c + + + romapi_dma.c + 1 + .\romapi_dma.c + + + romapi_i2cm.c + 1 + .\romapi_i2cm.c + + + romapi_i2cmon.c + 1 + .\romapi_i2cmon.c + + + romapi_i2cs.c + 1 + .\romapi_i2cs.c + + + romapi_spim.c + 1 + .\romapi_spim.c + + + romapi_spis.c + 1 + .\romapi_spis.c + + + romapi_uart.c + 1 + .\romapi_uart.c + + + rtc_ut.c + 1 + ..\chip_common\rtc_ut.c + + + pll_5410x.c + 1 + .\pll_5410x.c + + + hw_adc.c + 1 + .\hw_adc.c + + + hw_dmaaltd.c + 1 + .\hw_dmaaltd.c + + + hw_dmaaltd_rom_api.c + 1 + .\hw_dmaaltd_rom_api.c + + + hw_i2cmd.c + 1 + .\hw_i2cmd.c + + + hw_i2cmd_rom_api.c + 1 + .\hw_i2cmd_rom_api.c + + + hw_i2cmond.c + 1 + .\hw_i2cmond.c + + + hw_i2cmond_rom_api.c + 1 + .\hw_i2cmond_rom_api.c + + + hw_i2csd.c + 1 + .\hw_i2csd.c + + + hw_i2csd_rom_api.c + 1 + .\hw_i2csd_rom_api.c + + + hw_spimd_rom_api.c + 1 + .\hw_spimd_rom_api.c + + + hw_spisd.c + 1 + .\hw_spisd.c + + + hw_spisd_rom_api.c + 1 + .\hw_spisd_rom_api.c + + + hw_spimd.c + 1 + .\hw_spimd.c + + + hw_uart.c + 1 + .\hw_uart.c + + + fifo_5410x.c + 1 + .\fifo_5410x.c + + + + + lib + + + lib_power.lib + 4 + .\power_lib\keil\lib_power.lib + + + + + + + +
diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.ewp b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.ewp new file mode 100644 index 0000000000000000000000000000000000000000..c81958e00e1734dbf750e25c4f6ce35cb46dc421 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.ewp @@ -0,0 +1,1089 @@ + + + + 2 + + chip_5410x_lib + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + csp + + $PROJ_DIR$\chip_5410x.c + + + $PROJ_DIR$\clock_5410x.c + + + $PROJ_DIR$\crc_5410x.c + + + $PROJ_DIR$\gpio_5410x.c + + + $PROJ_DIR$\gpiogroup_5410x.c + + + $PROJ_DIR$\hw_adc.c + + + $PROJ_DIR$\hw_dmaaltd.c + + + $PROJ_DIR$\hw_dmaaltd_rom_api.c + + + $PROJ_DIR$\hw_i2cmd.c + + + $PROJ_DIR$\hw_i2cmd_rom_api.c + + + $PROJ_DIR$\hw_i2cmond.c + + + $PROJ_DIR$\hw_i2cmond_rom_api.c + + + $PROJ_DIR$\hw_i2csd.c + + + $PROJ_DIR$\hw_i2csd_rom_api.c + + + $PROJ_DIR$\hw_spimd.c + + + $PROJ_DIR$\hw_spimd_rom_api.c + + + $PROJ_DIR$\hw_spisd.c + + + $PROJ_DIR$\hw_spisd_rom_api.c + + + $PROJ_DIR$\hw_uart.c + + + $PROJ_DIR$\fifo_5410x.c + + + $PROJ_DIR$\iocon_5410x.c + + + $PROJ_DIR$\pinint_5410x.c + + + $PROJ_DIR$\pll_5410x.c + + + $PROJ_DIR$\..\chip_common\ring_buffer.c + + + $PROJ_DIR$\ritimer_5410x.c + + + $PROJ_DIR$\romapi_adc.c + + + $PROJ_DIR$\romapi_dma.c + + + $PROJ_DIR$\romapi_i2cm.c + + + $PROJ_DIR$\romapi_i2cmon.c + + + $PROJ_DIR$\romapi_i2cs.c + + + $PROJ_DIR$\romapi_spim.c + + + $PROJ_DIR$\romapi_spis.c + + + $PROJ_DIR$\romapi_uart.c + + + $PROJ_DIR$\rtc_5410x.c + + + $PROJ_DIR$\..\chip_common\rtc_ut.c + + + $PROJ_DIR$\sct_5410x.c + + + $PROJ_DIR$\sct_pwm_5410x.c + + + $PROJ_DIR$\stopwatch_5410x.c + + + $PROJ_DIR$\syscon_5410x.c + + + $PROJ_DIR$\sysinit_5410x.c + + + $PROJ_DIR$\timer_5410x.c + + + $PROJ_DIR$\utick_5410x.c + + + $PROJ_DIR$\wwdt_5410x.c + + + + libs + + $PROJ_DIR$\power_lib\iar\lib_power.a + + + + + diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.uvprojx b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..d58f5367bd5e9b24c72a21829651fd658990f28a --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/lib_chip_5410x_m0.uvprojx @@ -0,0 +1,652 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + lib_chip_5410x_m0 + 0x4 + ARM-ADS + + + LPC54102:M0plus + NXP + Keil.LPC54000_DFP.0.0.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x02000000,0x10000) IRAM2(0x02010000,0x08000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + 0 + $$Device:LPC54102$Device\Include\LPC54xxx.h + + + + + + + + + + $$Device:LPC54102$SVD\LPC54xxx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\keil_output\core_m0\ + lib_chip_5410x_m0 + 0 + 1 + 0 + 1 + 1 + .\keil_output\core_m4\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + + 0 + 1 + + + + + + + + + + + + + + BIN\UL2CM3.DLL + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 0 + 0x2010000 + 0x8000 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + + + CORE_M0PLUS + + .\config;..\chip_5410x;..\chip_common;..\..\..\CMSIS\CMSIS\Include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x00000000 + + + + + + + + + + + + + csp + + + ring_buffer.c + 1 + ..\chip_common\ring_buffer.c + + + chip_5410x.c + 1 + .\chip_5410x.c + + + clock_5410x.c + 1 + .\clock_5410x.c + + + crc_5410x.c + 1 + .\crc_5410x.c + + + gpio_5410x.c + 1 + .\gpio_5410x.c + + + iocon_5410x.c + 1 + .\iocon_5410x.c + + + pinint_5410x.c + 1 + .\pinint_5410x.c + + + sct_5410x.c + 1 + .\sct_5410x.c + + + sct_pwm_5410x.c + 1 + .\sct_pwm_5410x.c + + + syscon_5410x.c + 1 + .\syscon_5410x.c + + + sysinit_5410x.c + 1 + .\sysinit_5410x.c + + + timer_5410x.c + 1 + .\timer_5410x.c + + + utick_5410x.c + 1 + .\utick_5410x.c + + + wwdt_5410x.c + 1 + .\wwdt_5410x.c + + + rtc_5410x.c + 1 + .\rtc_5410x.c + + + fpu_init.c + 1 + ..\chip_common\fpu_init.c + + + iap.c + 1 + ..\chip_common\iap.c + + + gpiogroup_5410x.c + 1 + .\gpiogroup_5410x.c + + + stopwatch_5410x.c + 1 + .\stopwatch_5410x.c + + + ritimer_5410x.c + 1 + .\ritimer_5410x.c + + + romapi_adc.c + 1 + .\romapi_adc.c + + + romapi_dma.c + 1 + .\romapi_dma.c + + + romapi_i2cm.c + 1 + .\romapi_i2cm.c + + + romapi_i2cmon.c + 1 + .\romapi_i2cmon.c + + + romapi_i2cs.c + 1 + .\romapi_i2cs.c + + + romapi_spim.c + 1 + .\romapi_spim.c + + + romapi_spis.c + 1 + .\romapi_spis.c + + + romapi_uart.c + 1 + .\romapi_uart.c + + + rtc_ut.c + 1 + ..\chip_common\rtc_ut.c + + + pll_5410x.c + 1 + .\pll_5410x.c + + + hw_adc.c + 1 + .\hw_adc.c + + + hw_dmaaltd.c + 1 + .\hw_dmaaltd.c + + + hw_dmaaltd_rom_api.c + 1 + .\hw_dmaaltd_rom_api.c + + + hw_i2cmd.c + 1 + .\hw_i2cmd.c + + + hw_i2cmd_rom_api.c + 1 + .\hw_i2cmd_rom_api.c + + + hw_i2cmond.c + 1 + .\hw_i2cmond.c + + + hw_i2cmond_rom_api.c + 1 + .\hw_i2cmond_rom_api.c + + + hw_i2csd.c + 1 + .\hw_i2csd.c + + + hw_i2csd_rom_api.c + 1 + .\hw_i2csd_rom_api.c + + + hw_spimd_rom_api.c + 1 + .\hw_spimd_rom_api.c + + + hw_spisd.c + 1 + .\hw_spisd.c + + + hw_spisd_rom_api.c + 1 + .\hw_spisd_rom_api.c + + + hw_spimd.c + 1 + .\hw_spimd.c + + + hw_uart.c + 1 + .\hw_uart.c + + + fifo_5410x.c + 1 + .\fifo_5410x.c + + + + + lib + + + lib_power_m0.lib + 4 + .\power_lib\keil\lib_power_m0.lib + + + + + + + +
diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mailbox_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mailbox_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..b28ddeaa3a8f5643a2779c9bce1d05e753c480fe --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mailbox_5410x.h @@ -0,0 +1,173 @@ +/* + * @brief LPC5410X Mailbox M4/M0+ 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 __MAILBOX_5410X_H_ +#define __MAILBOX_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup MAILBOX_5410X CHIP: LPC5410X Mailbox M4/M0+ driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/* Mailbox indexes */ +typedef enum { + MAILBOX_CM0PLUS = 0, + MAILBOX_CM4 +} MBOX_IDX_T; +#define MAILBOX_AVAIL (MAILBOX_CM4 + 1) /* Number of available mailboxes */ + +/** Individual mailbox IRQ structure */ +typedef struct { + __IO uint32_t IRQ; /*!< Mailbox data */ + __O uint32_t IRQSET; /*!< Mailbox data set bits only */ + __O uint32_t IRQCLR; /*!< Mailbox dataclearset bits only */ + __I uint32_t RESERVED; +} LPC_MBOXIRQ_T; + +/** Mailbox register structure */ +typedef struct { /*!< Mailbox register structure */ + LPC_MBOXIRQ_T BOX[MAILBOX_AVAIL]; /*!< Mailbox, offset 0 = M0+, offset 1 = M4 */ + LPC_MBOXIRQ_T RESERVED1[15 - MAILBOX_AVAIL]; + __I uint32_t RESERVED2[2]; + __IO uint32_t MUTEX; /*!< Mutex */ +} LPC_MBOX_T; + +/** + * @brief Initialize mailbox + * @param pMBOX : Pointer to the mailbox register structure + * @return Nothing + * @note Even if both cores use the amilbox, only 1 core should initialize it. + */ +STATIC INLINE void Chip_MBOX_Init(LPC_MBOX_T *pMBOX) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_MAILBOX); + Chip_SYSCON_PeriphReset(RESET_MAILBOX); +} + +/** + * @brief Shutdown mailbox + * @param pMBOX : Pointer to the mailbox register structure + * @return Nothing + */ +STATIC INLINE void Chip_MBOX_DeInit(LPC_MBOX_T *pMBOX) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_MAILBOX); +} + +/** + * @brief Set data value in the mailbox based on the CPU ID + * @param pMBOX : Pointer to the mailbox register structure + * @param cpu_id : MAILBOX_CM0PLUS is M0+ or MAILBOX_CM4 is M4 + * @param mboxData : data to send in the mailbox + * @return Nothing + * @note Sets a data value to send via the MBOX to the other core. + */ +STATIC INLINE void Chip_MBOX_SetValue(LPC_MBOX_T *pMBOX, uint32_t cpu_id, uint32_t mboxData) +{ + pMBOX->BOX[cpu_id].IRQ = mboxData; +} + +/** + * @brief Set data bits in the mailbox based on the CPU ID + * @param pMBOX : Pointer to the mailbox register structure + * @param cpu_id : MAILBOX_CM0PLUS is M0+ or MAILBOX_CM4 is M4 + * @param mboxSetBits : data bits to set in the mailbox + * @return Nothing + * @note Sets data bits to send via the MBOX to the other core, A value of 0 will + * do nothing. Only sets bits selected with a 1 in it's bit position. + */ +STATIC INLINE void Chip_MBOX_SetValueBits(LPC_MBOX_T *pMBOX, uint32_t cpu_id, uint32_t mboxSetBits) +{ + pMBOX->BOX[cpu_id].IRQSET = mboxSetBits; +} + +/** + * @brief Clear data bits in the mailbox based on the CPU ID + * @param pMBOX : Pointer to the mailbox register structure + * @param cpu_id : MAILBOX_CM0PLUS is M0+ or MAILBOX_CM4 is M4 + * @param mboxClrBits : data bits to clear in the mailbox + * @return Nothing + * @note Clear data bits to send via the MBOX to the other core. A value of 0 will + * do nothing. Only clears bits selected with a 1 in it's bit position. + */ +STATIC INLINE void Chip_MBOX_ClearValueBits(LPC_MBOX_T *pMBOX, uint32_t cpu_id, uint32_t mboxClrBits) +{ + pMBOX->BOX[cpu_id].IRQCLR = mboxClrBits; +} + +/** + * @brief Get data in the mailbox based on the cpu_id + * @param pMBOX : Pointer to the mailbox register structure + * @param cpu_id : MAILBOX_CM0PLUS is M0+ or MAILBOX_CM4 is M4 + * @return Current mailbox data + */ +STATIC INLINE uint32_t Chip_MBOX_GetValue(LPC_MBOX_T *pMBOX, uint32_t cpu_id) +{ + return pMBOX->BOX[cpu_id].IRQ; +} + +/** + * @brief Get MUTEX state and lock mutex + * @param pMBOX : Pointer to the mailbox register structure + * @return See note + * @note Returns '1' if the mutex was taken or '0' if another resources has the + * mutex locked. Once a mutex is taken, it can be returned with the Chip_MBOX_SetMutex() + * function. + */ +STATIC INLINE uint32_t Chip_MBOX_GetMutex(LPC_MBOX_T *pMBOX) +{ + return pMBOX->MUTEX; +} + +/** + * @brief Set MUTEX state + * @param pMBOX : Pointer to the mailbox register structure + * @return Nothing + * @note Sets mutex state to '1' and allows other resources to get the mutex + */ +STATIC INLINE void Chip_MBOX_SetMutex(LPC_MBOX_T *pMBOX) +{ + pMBOX->MUTEX = 1; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAILBOX_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mrt_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mrt_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..c2b4639da332d4313343dd812e7d3d1984e55bfe --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/mrt_5410x.h @@ -0,0 +1,340 @@ +/* + * @brief LPC5410X Multi-Rate Timer (MRT) registers and driver functions + * + * @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 __MRT_5410X_H_ +#define __MRT_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup MRT_5410X CHIP: LPC5410X Multi-Rate Timer driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X 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[44]; + __IO uint32_t MODCFG; + __O uint32_t IDLE_CH; + __IO uint32_t IRQ_FLAG; +} LPC_MRT_T; + +/** + * @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 (0x7FFFFFFF) /* 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(SYSCON_CLOCK_MRT); + + /* Reset MRT */ + Chip_SYSCON_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(SYSCON_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.
+ * Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately
+ * 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; +} + +/** + * @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; +} + +/** + * @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; + 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; +} + +/** + * @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_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..6b3d380c199aae3464a5d84f52d1b60b05fc2f8d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.c @@ -0,0 +1,79 @@ +/* + * @brief LPC5410X Pin Interrupt and Pattern Match Registers and 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set source for pattern match engine */ +void Chip_PININT_SetPatternMatchSrc(LPC_PIN_INT_T *pPININT, + Chip_PININT_SELECT_T channelNum, + Chip_PININT_BITSLICE_T sliceNum) +{ + uint32_t pmsrc_reg; + + /* Source source for pattern matching */ + pmsrc_reg = pPININT->PMSRC & ~(PININT_SRC_BITSOURCE_MASK << (PININT_SRC_BITSOURCE_START + (sliceNum * 3))); + pPININT->PMSRC = pmsrc_reg | (channelNum << (PININT_SRC_BITSOURCE_START + (sliceNum * 3))); +} + +/* Configure Pattern match engine */ +void Chip_PININT_SetPatternMatchConfig(LPC_PIN_INT_T *pPININT, Chip_PININT_BITSLICE_T sliceNum, + 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 + (sliceNum * 3))); + pPININT->PMCFG = pmcfg_reg | (slice_cfg << (PININT_SRC_BITCFG_START + (sliceNum * 3))); + + /* If end point is true, enable the bits */ + if (end_point == true) { + /* By default slice 7 is final component */ + if (sliceNum != PININTBITSLICE7) { + pPININT->PMCFG |= (0x1 << sliceNum); + } + } +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..668860a10eefd24d6522919fcb746a6436cb1672 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pinint_5410x.h @@ -0,0 +1,413 @@ +/* + * @brief LPC5410X Pin Interrupt and Pattern Match Registers and 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 __PININT_5410X_H_ +#define __PININT_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PININT_5410X CHIP: LPC5410X Pin Interrupt and Pattern Match driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X Pin Interrupt and Pattern Match register block structure + */ +typedef struct { /*!< PIN_INT Structure */ + __IO uint32_t ISEL; /*!< Pin Interrupt Mode register */ + __IO uint32_t IENR; /*!< Pin Interrupt Enable (Rising) register */ + __IO uint32_t SIENR; /*!< Set Pin Interrupt Enable (Rising) register */ + __IO uint32_t CIENR; /*!< Clear Pin Interrupt Enable (Rising) register */ + __IO uint32_t IENF; /*!< Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t SIENF; /*!< Set Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t CIENF; /*!< Clear Pin Interrupt Enable Falling Edge / Active Level address */ + __IO uint32_t RISE; /*!< Pin Interrupt Rising Edge register */ + __IO uint32_t FALL; /*!< Pin Interrupt Falling Edge register */ + __IO uint32_t IST; /*!< Pin Interrupt Status register */ + __IO uint32_t PMCTRL; /*!< GPIO pattern match interrupt control register */ + __IO uint32_t PMSRC; /*!< GPIO pattern match interrupt bit-slice source register */ + __IO uint32_t PMCFG; /*!< GPIO pattern match interrupt bit slice configuration register */ +} LPC_PIN_INT_T; + +/** + * LPC5410X Pin Interrupt and Pattern match engine register + * bit fields and macros + */ + +/* PININT Interrupt Mode Mask */ +#define PININT_ISEL_PMODE_MASK ((uint32_t) 0x00FF) + +/* PININT Pattern Match Control Register Mask */ +#define PININT_PMCTRL_MASK ((uint32_t) 0xFF000003) + +/* 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 + +/** + * LPC5410X 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)) + +/** + * LPC5410X Pin Interrupt select enum values + */ +typedef enum Chip_PININT_SELECT { + PININTSELECT0 = 0, + PININTSELECT1 = 1, + PININTSELECT2 = 2, + PININTSELECT3 = 3, + PININTSELECT4 = 4, + PININTSELECT5 = 5, + PININTSELECT6 = 6, + PININTSELECT7 = 7 +} Chip_PININT_SELECT_T; + +/** + * LPC5410X 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; + +/** + * LPC5410X 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_PATTERNRISINGORFALLING = 0x3, /*!< Rising or Falling edge */ + PININT_PATTERNHIGH = 0x4, /*!< High level */ + PININT_PATTERNLOW = 0x5, /*!< Low level */ + PININT_PATTERNCONST0 = 0x6, /*!< Never contributes for match */ + PININT_PATTERNEVENT = 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_PIN_INT_T *pPININT) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_PINT); + Chip_SYSCON_PeriphReset(RESET_PINT); +} + +/** + * @brief De-Initialize Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @return Nothing + */ +STATIC INLINE void Chip_PININT_DeInit(LPC_PIN_INT_T *pPININT) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_PINT); +} + +/** + * @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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->ISEL = (pPININT->ISEL & PININT_ISEL_PMODE_MASK) & ~pins; +} + +/** + * @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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->ISEL = (pPININT->ISEL & PININT_ISEL_PMODE_MASK) | pins; +} + +/** + * @brief Return current PININT edge or level sensitive interrupt selection state + * @param pPININT : The base address of Pin interrupt block + * @return A bifield containing the edge/level sensitive selection for each + * interrupt. Bit 0 = PININT0, 1 = PININT1, etc. + * For each bit, a 0 means the edge sensitive interrupt is selected, while a 1 + * means the level sensitive interrupt is selected. + */ +STATIC INLINE uint32_t Chip_PININT_GetPinMode(LPC_PIN_INT_T *pPININT) +{ + return pPININT->ISEL & PININT_ISEL_PMODE_MASK; +} + +/** + * @brief Return current PININT rising edge or level interrupt enable state + * @param pPININT : The base address of Pin interrupt block + * @return A bifield containing the rising edge/level enable for each + * interrupt. Bit 0 = PININT0, 1 = PININT1, etc. + * For each bit, a 0 means the rising edge/level interrupt is disabled, while a 1 + * means it's enabled. + */ +STATIC INLINE uint32_t Chip_PININT_GetHighEnabled(LPC_PIN_INT_T *pPININT) +{ + return pPININT->IENR; +} + +/** + * @brief Enable rising 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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->SIENR = pins; +} + +/** + * @brief Disable rising 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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->CIENR = pins; +} + +/** + * @brief Return current PININT falling edge or level interrupt active level enable state + * @param pPININT : The base address of Pin interrupt block + * @return A bifield containing the falling edge/level interrupt active level enable for each + * interrupt. Bit 0 = PININT0, 1 = PININT1, etc. + * For each bit, a 0 means the falling edge is disabled/level interrupt active low is enabled, while a 1 + * means the falling edge is enabled/level interrupt active high is enabled. + */ +STATIC INLINE uint32_t Chip_PININT_GetLowEnabled(LPC_PIN_INT_T *pPININT) +{ + return pPININT->IENF; +} + +/** + * @brief Enable falling edge/level active 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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->SIENF = pins; +} + +/** + * @brief Disable low edge/level active 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_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->CIENF = pins; +} + +/** + * @brief Return pin states that have a detected latched rising 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_PIN_INT_T *pPININT) +{ + return pPININT->RISE; +} + +/** + * @brief Clears pin states that had a latched rising 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_PIN_INT_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_PIN_INT_T *pPININT) +{ + return pPININT->FALL; +} + +/** + * @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_PIN_INT_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_PIN_INT_T *pPININT) +{ + return pPININT->IST; +} + +/** + * @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_PIN_INT_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 channelNum : PININT channel number (From 0 to 7) + * @param sliceNum : PININT slice number + * @return Nothing + */ +void Chip_PININT_SetPatternMatchSrc(LPC_PIN_INT_T *pPININT, + Chip_PININT_SELECT_T channelNum, + Chip_PININT_BITSLICE_T sliceNum); + +/** + * @brief Configure the pattern matcch in Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @param sliceNum : 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_PIN_INT_T *pPININT, Chip_PININT_BITSLICE_T sliceNum, + 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_PIN_INT_T *pPININT) +{ + pPININT->PMCTRL = (pPININT->PMCTRL & PININT_PMCTRL_MASK) | PININT_PMCTRL_PMATCH_SEL; +} + +/** + * @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_PIN_INT_T *pPININT) +{ + pPININT->PMCTRL = (pPININT->PMCTRL & PININT_PMCTRL_MASK) & ~PININT_PMCTRL_PMATCH_SEL; +} + +/** + * @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_PIN_INT_T *pPININT) +{ + pPININT->PMCTRL = (pPININT->PMCTRL & PININT_PMCTRL_MASK) | PININT_PMCTRL_RXEV_ENA; +} + +/** + * @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_PIN_INT_T *pPININT) +{ + pPININT->PMCTRL = (pPININT->PMCTRL & PININT_PMCTRL_MASK) & ~PININT_PMCTRL_RXEV_ENA; +} + +/** + * @brief Return pattern match state + * @param pPININT : The base address of Pin interrupt block + * @return 8 bit pattern match state, where a 1 in any bit indicates that + * the corresponding product term has matched by the current state + * of its inputs. + */ +STATIC INLINE uint32_t Chip_PININT_GetPatternMatchState(LPC_PIN_INT_T *pPININT) +{ + return pPININT->PMCTRL >> 24; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PININT_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pintable_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pintable_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..ab7119485ca844779b5136746b75b997d0b75de3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pintable_5410x.h @@ -0,0 +1,86 @@ +/* + * @brief LPC5410x enhanced boot block + * + * @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 __PINTABLE_5410X_H_ +#define __PINTABLE_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PINTAB_5410X CHIP: LPC5410X Enhanced boot block support + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X Pin table structure used for enhanced boot block support + */ +struct PINTABLE { + /* pin table marker: Should be 0xFEEDA5A5 */ + uint32_t marker; + /* img_type: + 0 = Normal image check IRQ line to halt boot + 1 = Wait for AP to send SH_CMD_BOOT command + 2 = Boot image with no AP checks + 3 = No CRC or AP checks needed. Used during development */ + uint8_t img_type; + /* ifSel: Interface selection for host + (0,=AUTODETECT, 1=I2C0, 2=I2C1, 3=I2C2, 4=SPI0, 5=SPI1) */ + uint8_t ifSel; + /* hostIrqPortPin: Host IRQ port (bits 7:5) and pins (bits 4:0) */ + uint8_t hostIrqPortPin; + /* hostMisoPortPin: SPI MISO port (bits 7:5) and pins (bits 4:0) */ + uint8_t hostMisoPortPin; + /* hostMosiPortPin: SPI MOSI port (bits 7:5) and pins (bits 4:0) */ + uint8_t hostMosiPortPin; + /* hostSselPortPin: SPI SEL port (bits 7:5) and pins (bits 4:0) */ + uint8_t hostSselPortPin; + /* hostSckPortPin: SPI SCK port (bits 7:5) and pins (bits 4:0) */ + uint8_t hostSckPortPin; + /* xorVal: XOR value of the 7 bytes above */ + uint8_t xorVal; + /* CRC32 length and value fields */ + uint32_t crc32_len; + uint32_t crc32_val; + /* Application image version number */ + uint32_t version; +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PINTAB_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..d99fd859166f71f66934215abfe1d760f66175c7 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.c @@ -0,0 +1,866 @@ +/* + * @brief LPC5410X PLL 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 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 + ****************************************************************************/ + +#define NVALMAX (0x100) +#define PVALMAX (0x20) +#define MVALMAX (0x8000) + +/* SYS PLL related bit fields */ +#define SYS_PLL_SELR(d) (((d) & 0xf) << 0) /*!< Bandwidth select R value */ +#define SYS_PLL_SELI(d) (((d) & 0x3f) << 4) /*!< Bandwidth select I value */ +#define SYS_PLL_SELP(d) (((d) & 0x1f) << 10) /*!< Bandwidth select P value */ +#define SYS_PLL_BYPASS (1 << 15) /*!< Enable PLL bypass */ +#define SYS_PLL_BYPASSCCODIV2 (1 << 16) /*!< Enable bypass of extra divider by 2 */ +#define SYS_PLL_UPLIMOFF (1 << 17) /*!< Enable spread spectrum/fractional mode */ +#define SYS_PLL_BANDSEL (1 << 18) /*!< Enable MDEC control */ +#define SYS_PLL_DIRECTI (1 << 19) /*!< PLL0 direct input enable */ +#define SYS_PLL_DIRECTO (1 << 20) /*!< PLL0 direct output enable */ + +// #define FRAC_BITS_SELI (8) // For retaining fractions in divisions +#define PLL_SSCG0_MDEC_VAL_P (0) // MDEC is in bits 16 downto 0 +#define PLL_SSCG0_MDEC_VAL_M (0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P) // NDEC is in bits 9 downto 0 +#define PLL_NDEC_VAL_P (0) // NDEC is in bits 9:0 +#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P) +#define PLL_PDEC_VAL_P (0) // PDEC is in bits 6:0 +#define PLL_PDEC_VAL_M (0x3FFUL << PLL_PDEC_VAL_P) + +#define PLL_MIN_CCO_FREQ_MHZ (75000000) +#define PLL_MAX_CCO_FREQ_MHZ (150000000) +#define PLL_LOWER_IN_LIMIT (4000) /*!< Minimum PLL input rate */ +#define PLL_MIN_IN_SSMODE (2000000) +#define PLL_MAX_IN_SSMODE (4000000) + +// Middle of the range values for spread-spectrum +#define PLL_SSCG_MF_FREQ_VALUE 4 +#define PLL_SSCG_MC_COMP_VALUE 2 +#define PLL_SSCG_MR_DEPTH_VALUE 4 +#define PLL_SSCG_DITHER_VALUE 0 + +// pll SYSPLLCTRL Bits +#define SYSCON_SYSPLLCTRL_SELR_P 0 +#define SYSCON_SYSPLLCTRL_SELR_M (0xFUL << SYSCON_SYSPLLCTRL_SELR_P) +#define SYSCON_SYSPLLCTRL_SELI_P 4 +#define SYSCON_SYSPLLCTRL_SELI_M (0x3FUL << SYSCON_SYSPLLCTRL_SELI_P) +#define SYSCON_SYSPLLCTRL_SELP_P 10 +#define SYSCON_SYSPLLCTRL_SELP_M (0x1FUL << SYSCON_SYSPLLCTRL_SELP_P) +#define SYSCON_SYSPLLCTRL_BYPASS_P 15 // sys_pll150_ctrl +#define SYSCON_SYSPLLCTRL_BYPASS (1UL << SYSCON_SYSPLLCTRL_BYPASS_P) +#define SYSCON_SYSPLLCTRL_BYPASS_FBDIV2_P 16 +#define SYSCON_SYSPLLCTRL_BYPASS_FBDIV2 (1UL << SYSCON_SYSPLLCTRL_BYPASS_FBDIV2_P) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_P 17 +#define SYSCON_SYSPLLCTRL_UPLIMOFF (1UL << SYSCON_SYSPLLCTRL_UPLIMOFF_P) +#define SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N_P 18 +#define SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N (1UL << SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N_P) +#define SYSCON_SYSPLLCTRL_DIRECTI_P 19 +#define SYSCON_SYSPLLCTRL_DIRECTI (1UL << SYSCON_SYSPLLCTRL_DIRECTI_P) +#define SYSCON_SYSPLLCTRL_DIRECTO_P 20 +#define SYSCON_SYSPLLCTRL_DIRECTO (1UL << SYSCON_SYSPLLCTRL_DIRECTO_P) + +#define SYSCON_SYSPLLSTAT_LOCK_P 0 +#define SYSCON_SYSPLLSTAT_LOCK (1UL << SYSCON_SYSPLLSTAT_LOCK_P) + +#define PLL_CTRL_BYPASS_P 15 // sys_pll150_ctrl +#define PLL_CTRL_BYPASS_FBDIV2_P 16 +#define PLL_CTRL_UPLIMOFF_P 17 +#define PLL_CTRL_BANDSEL_SSCGREG_N_P 18 +#define PLL_CTRL_DIRECTI_P 19 +#define PLL_CTRL_DIRECTO_P 20 + +#define PLL_CTRL_BYPASS (1 << PLL_CTRL_BYPASS_P) +#define PLL_CTRL_DIRECTI (1 << PLL_CTRL_DIRECTI_P) +#define PLL_CTRL_DIRECTO (1 << PLL_CTRL_DIRECTO_P) +#define PLL_CTRL_UPLIMOFF (1 << PLL_CTRL_UPLIMOFF_P) +#define PLL_CTRL_BANDSEL_SSCGREG_N (1 << PLL_CTRL_BANDSEL_SSCGREG_N_P) +#define PLL_CTRL_BYPASS_FBDIV2 (1 << PLL_CTRL_BYPASS_FBDIV2_P) + +// SSCG control[0] +// #define PLL_SSCG0_MDEC_VAL_P 0 // MDEC is in bits 16 downto 0 +#define PLL_SSCG0_MREQ_P 17 +#define PLL_SSCG0_SEL_EXT_SSCG_N_P 18 +#define PLL_SSCG0_SEL_EXT_SSCG_N (1 << PLL_SSCG0_SEL_EXT_SSCG_N_P) +#define PLL_SSCG0_MREQ (1 << PLL_SSCG0_MREQ_P) + +// SSCG control[1] +#define PLL_SSCG1_MD_REQ_P 19 +#define PLL_SSCG1_MOD_PD_SSCGCLK_N_P 28 +#define PLL_SSCG1_DITHER_P 29 +#define PLL_SSCG1_MOD_PD_SSCGCLK_N (1 << PLL_SSCG1_MOD_PD_SSCGCLK_N_P) +#define PLL_SSCG1_DITHER (1 << PLL_SSCG1_DITHER_P) +#define PLL_SSCG1_MD_REQ (1 << PLL_SSCG1_MD_REQ_P) + +// PLL NDEC reg +#define PLL_NDEC_VAL_SET(value) (((unsigned long) (value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M) +#define PLL_NDEC_NREQ_P 10 +#define PLL_NDEC_NREQ (1 << PLL_NDEC_NREQ_P) + +// PLL PDEC reg +#define PLL_PDEC_VAL_SET(value) (((unsigned long) (value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M) +#define PLL_PDEC_PREQ_P 7 +#define PLL_PDEC_PREQ (1 << PLL_PDEC_PREQ_P) + +// SSCG control[0] +#define PLL_SSCG0_MDEC_VAL_SET(value) (((unsigned long) (value) << PLL_SSCG0_MDEC_VAL_P) & PLL_SSCG0_MDEC_VAL_M) +#define PLL_SSCG0_MREQ_P 17 +#define PLL_SSCG0_MREQ (1 << PLL_SSCG0_MREQ_P) +#define PLL_SSCG0_SEL_EXT_SSCG_N_P 18 +#define PLL_SSCG0_SEL_EXT_SSCG_N (1 << PLL_SSCG0_SEL_EXT_SSCG_N_P) + +// SSCG control[1] +#define PLL_SSCG1_MD_FRACT_P 0 +#define PLL_SSCG1_MD_INT_P 11 +#define PLL_SSCG1_MF_P 20 +#define PLL_SSCG1_MC_P 26 +#define PLL_SSCG1_MR_P 23 + +#define PLL_SSCG1_MD_FRACT_M (0x7FFUL << PLL_SSCG1_MD_FRACT_P) +#define PLL_SSCG1_MD_INT_M (0xFFUL << PLL_SSCG1_MD_INT_P) +#define PLL_SSCG1_MF_M (0x7UL << PLL_SSCG1_MF_P) +#define PLL_SSCG1_MC_M (0x3UL << PLL_SSCG1_MC_P) +#define PLL_SSCG1_MR_M (0x7UL << PLL_SSCG1_MR_P) + +#define PLL_SSCG1_MD_FRACT_SET(value) (((unsigned long) (value) << \ + PLL_SSCG1_MD_FRACT_P) & PLL_SSCG1_MD_FRACT_M) +#define PLL_SSCG1_MD_INT_SET(value) (((unsigned long) (value) << \ + PLL_SSCG1_MD_INT_P) & PLL_SSCG1_MD_INT_M) +// #define PLL_SSCG1_MF_SET(value) (((unsigned long) (value) << \ +// // PLL_SSCG1_MF_P) & PLL_SSCG1_MF_M) +// #define PLL_SSCG1_MC_SET(value) (((unsigned long) (value) << \ +// // PLL_SSCG1_MC_P) & PLL_SSCG1_MC_M) +// #define PLL_SSCG1_MR_SET(value) (((unsigned long) (value) << \ +// // PLL_SSCG1_MR_P) & PLL_SSCG1_MR_M) + +// Middle of the range values for spread-spectrum +#define PLL0_SSCG_MF_FREQ_VALUE 4 +#define PLL0_SSCG_MC_COMP_VALUE 2 +#define PLL0_SSCG_MR_DEPTH_VALUE 4 +#define PLL0_SSCG_DITHER_VALUE 0 + +#define PLL_MAX_N_DIV 0x100 + +/* Saved value of PLL output rate, computed whenever needed to save run-time + computation on each call to retrive the PLL rate. */ +static uint32_t curPllRate; + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Find encoded NDEC value for raw N value, max N = NVALMAX */ +static uint32_t pllEncodeN(uint32_t N) +{ + uint32_t x, i; + + /* Find NDec */ + switch (N) { + case 0: + x = 0xFFF; + break; + + case 1: + x = 0x302; + break; + + case 2: + x = 0x202; + break; + + default: + x = 0x080; + for (i = N; i <= NVALMAX; i++) { + x = (((x ^ (x >> 2) ^ (x >> 3) ^ (x >> 4)) & 1) << 7) | ((x >> 1) & 0x7F); + } + break; + } + + return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P); +} + +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC) +{ + uint32_t n, x, i; + + /* Find NDec */ + switch (NDEC) { + case 0xFFF: + n = 0; + break; + + case 0x302: + n = 1; + break; + + case 0x202: + n = 2; + break; + + default: + x = 0x080; + n = 0xFFFFFFFF; + for (i = NVALMAX; ((i >= 3) && (n == 0xFFFFFFFF)); i--) { + x = (((x ^ (x >> 2) ^ (x >> 3) ^ (x >> 4)) & 1) << 7) | ((x >> 1) & 0x7F); + if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC) { + /* Decoded value of NDEC */ + n = i; + } + } + break; + } + + return n; +} + +/* Find encoded PDEC value for raw P value, max P = PVALMAX */ +static uint32_t pllEncodeP(uint32_t P) +{ + uint32_t x, i; + + /* Find PDec */ + switch (P) { + case 0: + x = 0xFF; + break; + + case 1: + x = 0x62; + break; + + case 2: + x = 0x42; + break; + + default: + x = 0x10; + for (i = P; i <= PVALMAX; i++) { + x = (((x ^ (x >> 2)) & 1) << 4) | ((x >> 1) & 0xF); + } + break; + } + + return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P); +} + +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC) +{ + uint32_t p, x, i; + + /* Find PDec */ + switch (PDEC) { + case 0xFF: + p = 0; + break; + + case 0x62: + p = 1; + break; + + case 0x42: + p = 2; + break; + + default: + x = 0x10; + p = 0xFFFFFFFF; + for (i = PVALMAX; ((i >= 3) && (p == 0xFFFFFFFF)); i--) { + x = (((x ^ (x >> 2)) & 1) << 4) | ((x >> 1) & 0xF); + if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC) { + /* Decoded value of PDEC */ + p = i; + } + } + break; + } + + return p; +} + +/* Find encoded MDEC value for raw M value, max M = MVALMAX */ +static uint32_t pllEncodeM(uint32_t M) +{ + uint32_t i, x; + + /* Find MDec */ + switch (M) { + case 0: + x = 0xFFFFF; + break; + + case 1: + x = 0x18003; + break; + + case 2: + x = 0x10003; + break; + + default: + x = 0x04000; + for (i = M; i <= MVALMAX; i++) { + x = (((x ^ (x >> 1)) & 1) << 14) | ((x >> 1) & 0x3FFF); + } + break; + } + + return x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P); +} + +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC) +{ + uint32_t m, i, x; + + /* Find MDec */ + switch (MDEC) { + case 0xFFFFF: + m = 0; + break; + + case 0x18003: + m = 1; + break; + + case 0x10003: + m = 2; + break; + + default: + x = 0x04000; + m = 0xFFFFFFFF; + for (i = MVALMAX; ((i >= 3) && (m == 0xFFFFFFFF)); i--) { + x = (((x ^ (x >> 1)) & 1) << 14) | ((x >> 1) & 0x3FFF); + if ((x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P)) == MDEC) { + /* Decoded value of MDEC */ + m = i; + } + } + break; + } + + return m; +} + +/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */ +static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR) +{ + /* Bypass divider? */ + if (bypassFBDIV2) { + M = M / 2; + } + + /* bandwidth: compute selP from Multiplier */ + if (M < 60) { + *pSelP = (M >> 1) + 1; + } + else { + *pSelP = PVALMAX - 1; + } + + /* bandwidth: compute selI from Multiplier */ + if (M > 16384) { + *pSelI = 1; + } + else if (M > 8192) { + *pSelI = 2; + } + else if (M > 2048) { + *pSelI = 4; + } + else if (M >= 501) { + *pSelI = 8; + } + else if (M >= 60) { + *pSelI = 4 * (1024 / (M + 9)); + } + else { + *pSelI = (M & 0x3C) + 4; + } + + if (*pSelI > (SYSCON_SYSPLLCTRL_SELI_M >> SYSCON_SYSPLLCTRL_SELI_P)) { + *pSelI = (SYSCON_SYSPLLCTRL_SELI_M >> SYSCON_SYSPLLCTRL_SELI_P); + } + + *pSelR = 0; +} + +/* Get predivider (N) from PLL NDEC setting */ +uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg) +{ + uint32_t preDiv = 1; + + /* Direct input is not used? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTI) == 0) { + /* Decode NDEC value to get (N) pre divider */ + preDiv = pllDecodeN(nDecReg & 0x3FF); + if (preDiv == 0) { + preDiv = 1; + } + } + + /* Adjusted by 1, directi is used to bypass */ + return preDiv; +} + +/* Get postdivider (P) from PLL PDEC setting */ +uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg) +{ + uint32_t postDiv = 1; + + /* Direct input is not used? */ + if ((ctrlReg & SYS_PLL_DIRECTO) == 0) { + /* Decode PDEC value to get (P) post divider */ + postDiv = 2 * pllDecodeP(pDecReg & 0x7F); + if (postDiv == 0) { + postDiv = 2; + } + } + + /* Adjusted by 1, directo is used to bypass */ + return postDiv; +} + +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg) +{ + uint32_t mMult = 1; + + /* Decode MDEC value to get (M) multiplier */ + mMult = pllDecodeM(mDecReg & 0x1FFFF); + + /* Extra divided by 2 needed? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_BYPASS_FBDIV2) == 0) { + mMult = mMult >> 1; + } + + if (mMult == 0) { + mMult = 1; + } + + return mMult; +} + +static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n) +{ + uint32_t tmp; + + while (n != 0) { + tmp = n; + n = m % n; + m = tmp; + } + + return m; +} + +/* Set PLL output based on desired output rate */ +static PLL_ERROR_T Chip_Clock_GetPllConfig(uint32_t finHz, uint32_t foutHz, PLL_SETUP_T *pSetup, + bool useFeedbackDiv2, bool useSS) +{ + uint32_t nDivOutHz, fccoHz, multFccoDiv; + uint32_t pllPreDivider, pllMultiplier, pllBypassFBDIV2, pllPostDivider; + uint32_t pllDirectInput, pllDirectOutput; + uint32_t pllSelP, pllSelI, pllSelR, bandsel, uplimoff; + + /* Baseline parameters (no input or output dividers) */ + pllPreDivider = 1; /* 1 implies pre-divider will be disabled */ + pllPostDivider = 0; /* 0 implies post-divider will be disabled */ + pllDirectOutput = 1; + if (useFeedbackDiv2) { + /* Using feedback divider for M, so disable bypass */ + pllBypassFBDIV2 = 0; + } + else { + pllBypassFBDIV2 = 1; + } + multFccoDiv = (2 - pllBypassFBDIV2); + + /* Verify output rate parameter */ + if (foutHz > PLL_MAX_CCO_FREQ_MHZ) { + /* Maximum PLL output with post divider=1 cannot go above this frequency */ + return PLL_ERROR_OUTPUT_TOO_HIGH; + } + if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1))) { + /* Minmum PLL output with maximum post divider cannot go below this frequency */ + return PLL_ERROR_OUTPUT_TOO_LOW; + } + + /* If using SS mode, input clock needs to be between 2MHz and 4MHz */ + if (useSS) { + /* Verify input rate parameter */ + if (finHz < PLL_MIN_IN_SSMODE) { + /* Input clock into the PLL cannot be lower than this */ + return PLL_ERROR_INPUT_TOO_LOW; + } + + /* PLL input in SS mode must be under 4MHz */ + pllPreDivider = finHz / ((PLL_MIN_IN_SSMODE + PLL_MAX_IN_SSMODE) / 2); + if (pllPreDivider > NVALMAX) { + return PLL_ERROR_INPUT_TOO_HIGH; + } + } + else { + /* Verify input rate parameter */ + if (finHz < PLL_LOWER_IN_LIMIT) { + /* Input clock into the PLL cannot be lower than this */ + return PLL_ERROR_INPUT_TOO_LOW; + } + } + + /* Find the optimal CCO frequency for the output and input that + will keep it inside the PLL CCO range. This may require + tweaking the post-divider for the PLL. */ + fccoHz = foutHz; + while (fccoHz < PLL_MIN_CCO_FREQ_MHZ) { + /* CCO output is less than minimum CCO range, so the CCO output + needs to be bumped up and the post-divider is used to bring + the PLL output back down. */ + pllPostDivider++; + if (pllPostDivider > PVALMAX) { + return PLL_ERROR_OUTSIDE_INTLIMIT; + } + + /* Target CCO goes up, PLL output goes down */ + fccoHz = foutHz * (pllPostDivider * 2); + pllDirectOutput = 0; + } + + /* Determine if a pre-divider is needed to get the best frequency */ + if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false)) { + uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz)); + + if (a > 20000) { + a = (multFccoDiv * finHz) / a; + if ((a != 0) && (a < PLL_MAX_N_DIV)) { + pllPreDivider = a; + } + } + } + + /* Bypass pre-divider hardware if pre-divider is 1 */ + if (pllPreDivider > 1) { + pllDirectInput = 0; + } + else { + pllDirectInput = 1; + } + + /* Determine PLL multipler */ + nDivOutHz = (finHz / pllPreDivider); + pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv; + + /* Find optimal values for filter */ + if (useSS == false) { + /* Will bumping up M by 1 get us closer to the desired CCO frequency? */ + if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2) + 1)) < (fccoHz * 2)) { + pllMultiplier++; + } + + /* Setup filtering */ + pllFindSel(pllMultiplier, pllBypassFBDIV2, &pllSelP, &pllSelI, &pllSelR); + bandsel = 1; + uplimoff = 0; + + /* Get encoded value for M (mult) and use manual filter, disable SS mode */ + pSetup->SYSPLLSSCTRL[0] = (PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(pllMultiplier)) | + (1 << PLL_SSCG0_SEL_EXT_SSCG_N_P)); + + /* Power down SSC, not used */ + pSetup->SYSPLLSSCTRL[1] = PLL_SSCG1_MOD_PD_SSCGCLK_N; + } + else { + uint64_t fc; + + /* Filtering will be handled by SSC */ + pllSelR = pllSelI = pllSelP = 0; + bandsel = 0; + uplimoff = 1; + + /* The PLL multiplier will get very close and slightly under the + desired target frequency. A small fractional component can be + added to fine tune the frequency upwards to the target. */ + fc = ((uint64_t) (fccoHz % (multFccoDiv * nDivOutHz)) << 11) / (multFccoDiv * nDivOutHz); + + /* MDEC set by SSC */ + pSetup->SYSPLLSSCTRL[0] = 0; + + /* Set multiplier */ + pSetup->SYSPLLSSCTRL[1] = PLL_SSCG1_MD_INT_SET(pllMultiplier) | + PLL_SSCG1_MD_FRACT_SET((uint32_t) fc); + } + + /* Get encoded values for N (prediv) and P (postdiv) */ + pSetup->SYSPLLNDEC = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider)); + pSetup->SYSPLLPDEC = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider)); + + /* PLL control */ + pSetup->SYSPLLCTRL = + (pllSelR << SYSCON_SYSPLLCTRL_SELR_P) | /* Filter coefficient */ + (pllSelI << SYSCON_SYSPLLCTRL_SELI_P) | /* Filter coefficient */ + (pllSelP << SYSCON_SYSPLLCTRL_SELP_P) | /* Filter coefficient */ + (0 << SYSCON_SYSPLLCTRL_BYPASS_P) | /* PLL bypass mode disabled */ + (pllBypassFBDIV2 << SYSCON_SYSPLLCTRL_BYPASS_FBDIV2_P) | /* Extra M / 2 divider? */ + (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_P) | /* SS/fractional mode disabled */ + (bandsel << SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N_P) | /* Manual bandwidth selection enabled */ + (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_P) | /* Bypass pre-divider? */ + (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_P); /* Bypass post-divider? */ + + return PLL_ERROR_SUCCESS; +} + +/* Update local PLL rate variable */ +static void Chip_Clock_GetSystemPLLOutFromSetupUpdate(PLL_SETUP_T *pSetup) +{ + curPllRate = Chip_Clock_GetSystemPLLOutFromSetup(pSetup); +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Return System PLL input clock rate */ +uint32_t Chip_Clock_GetSystemPLLInClockRate(void) +{ + uint32_t clkRate = 0; + + switch ((CHIP_SYSCON_PLLCLKSRC_T) (LPC_SYSCON->SYSPLLCLKSEL & 0x3)) { + case SYSCON_PLLCLKSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCON_PLLCLKSRC_CLKIN: + clkRate = Chip_Clock_GetExtClockInRate(); + break; + + case SYSCON_PLLCLKSRC_WDTOSC: + clkRate = Chip_Clock_GetWDTOSCRate(); + break; + + case SYSCON_PLLCLKSRC_RTC: + clkRate = Chip_Clock_GetRTCOscRate(); + break; + } + + return clkRate; +} + +/* Return System PLL output clock rate from setup structure */ +uint32_t Chip_Clock_GetSystemPLLOutFromSetup(PLL_SETUP_T *pSetup) +{ + uint32_t prediv, postdiv, mMult, inPllRate; + uint64_t workRate; + + inPllRate = Chip_Clock_GetSystemPLLInClockRate(); + if ((pSetup->SYSPLLCTRL & SYSCON_SYSPLLCTRL_BYPASS_P) == 0) { + /* PLL is not in bypass mode, get pre-divider, post-divider, and M divider */ + prediv = findPllPreDiv(pSetup->SYSPLLCTRL, pSetup->SYSPLLNDEC); + postdiv = findPllPostDiv(pSetup->SYSPLLCTRL, pSetup->SYSPLLPDEC); + + /* Adjust input clock */ + inPllRate = inPllRate / prediv; + + /* If using the SS, use the multiplier */ + if (pSetup->SYSPLLSSCTRL[1] & PLL_SSCG1_MOD_PD_SSCGCLK_N) { + /* MDEC used for rate */ + mMult = findPllMMult(pSetup->SYSPLLCTRL, pSetup->SYSPLLSSCTRL[0]); + workRate = (uint64_t) inPllRate * (uint64_t) mMult; + } + else { + uint64_t fract; + + /* SS multipler used for rate */ + mMult = (pSetup->SYSPLLSSCTRL[1] & PLL_SSCG1_MD_INT_M) >> PLL_SSCG1_MD_INT_P; + workRate = (uint64_t) inPllRate * (uint64_t) mMult; + + /* Adjust by fractional */ + fract = (uint64_t) (pSetup->SYSPLLSSCTRL[1] & PLL_SSCG1_MD_FRACT_M) >> PLL_SSCG1_MD_FRACT_P; + workRate = workRate + ((inPllRate * fract) / 0x7FF); + } + + workRate = workRate / ((uint64_t) postdiv); + } + else { + /* In bypass mode */ + workRate = (uint64_t) inPllRate; + } + + return (uint32_t) workRate; +} + +/* Return System PLL output clock rate */ +uint32_t Chip_Clock_GetSystemPLLOutClockRate(bool recompute) +{ + PLL_SETUP_T Setup; + uint32_t rate; + + if ((recompute) || (curPllRate == 0)) { + Setup.SYSPLLCTRL = LPC_SYSCON->SYSPLLCTRL; + Setup.SYSPLLNDEC = LPC_SYSCON->SYSPLLNDEC; + Setup.SYSPLLPDEC = LPC_SYSCON->SYSPLLPDEC; + Setup.SYSPLLSSCTRL[0] = LPC_SYSCON->SYSPLLSSCTRL[0]; + Setup.SYSPLLSSCTRL[1] = LPC_SYSCON->SYSPLLSSCTRL[1]; + + Chip_Clock_GetSystemPLLOutFromSetupUpdate(&Setup); + } + + rate = curPllRate; + + return rate; +} + +/* Enables and disables PLL bypass mode */ +void Chip_Clock_SetBypassPLL(bool bypass) +{ + if (bypass) { + LPC_SYSCON->SYSPLLCTRL |= SYSCON_SYSPLLCTRL_BYPASS_P; + } + else { + LPC_SYSCON->SYSPLLCTRL &= ~SYSCON_SYSPLLCTRL_BYPASS_P; + } +} + +/* Set PLL output based on the passed PLL setup data */ +PLL_ERROR_T Chip_Clock_SetupPLLData(PLL_CONFIG_T *pControl, PLL_SETUP_T *pSetup) +{ + uint32_t inRate; + bool useSS = (bool) ((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0); + PLL_ERROR_T pllError; + + /* Determine input rate for the PLL */ + if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0) { + inRate = pControl->InputRate; + } + else { + inRate = Chip_Clock_GetSystemPLLInClockRate(); + } + + /* PLL flag options */ + pllError = Chip_Clock_GetPllConfig(inRate, pControl->desiredRate, pSetup, false, useSS); + if ((useSS) && (pllError == PLL_ERROR_SUCCESS)) { + /* If using SS mode, then some tweaks are made to the generated setup */ + pSetup->SYSPLLSSCTRL[1] |= (uint32_t) pControl->ss_mf | (uint32_t) pControl->ss_mr | + (uint32_t) pControl->ss_mc; + if (pControl->mfDither) { + pSetup->SYSPLLSSCTRL[1] |= PLL_SSCG1_DITHER; + } + } + + return pllError; +} + +/* Set PLL output from PLL setup structure */ +PLL_ERROR_T Chip_Clock_SetupSystemPLLPrec(PLL_SETUP_T *pSetup) +{ + /* Power off PLL during setup changes */ + Chip_SYSCON_PowerDown(SYSCON_PDRUNCFG_PD_SYS_PLL); + + /* Write PLL setup data */ + LPC_SYSCON->SYSPLLCTRL = pSetup->SYSPLLCTRL; + LPC_SYSCON->SYSPLLNDEC = pSetup->SYSPLLNDEC; + LPC_SYSCON->SYSPLLNDEC = pSetup->SYSPLLNDEC | PLL_NDEC_NREQ;/* latch */ + LPC_SYSCON->SYSPLLPDEC = pSetup->SYSPLLPDEC; + LPC_SYSCON->SYSPLLPDEC = pSetup->SYSPLLPDEC | PLL_PDEC_PREQ;/* latch */ + LPC_SYSCON->SYSPLLSSCTRL[0] = pSetup->SYSPLLSSCTRL[0]; + LPC_SYSCON->SYSPLLSSCTRL[0] = pSetup->SYSPLLSSCTRL[0] | PLL_SSCG0_MREQ; /* latch */ + LPC_SYSCON->SYSPLLSSCTRL[1] = pSetup->SYSPLLSSCTRL[1]; + LPC_SYSCON->SYSPLLSSCTRL[1] = pSetup->SYSPLLSSCTRL[1] | PLL_SSCG1_MD_REQ; /* latch */ + + /* Flags for lock or power on */ + if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0) { + Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_SYS_PLL); + } + if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0) { + while (Chip_Clock_IsSystemPLLLocked() == false) {} + } + + /* Update current programmed PLL rate var */ + Chip_Clock_GetSystemPLLOutFromSetupUpdate(pSetup); + + /* System voltage adjustment, occurs prior to setting main system clock */ + if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0) { + Chip_POWER_SetVoltage(POWER_LOW_POWER_MODE, curPllRate); + } + + return PLL_ERROR_SUCCESS; +} + +/* Set System PLL clock based on the input frequency and multiplier */ +void Chip_Clock_SetupSystemPLL(uint32_t multiply_by, uint32_t input_freq) +{ + uint32_t cco_freq = input_freq * multiply_by; + uint32_t pdec = 1; + uint32_t selr; + uint32_t seli; + uint32_t selp; + uint32_t mdec, ndec; + + uint32_t directo = SYS_PLL_DIRECTO; + + while (cco_freq < 75000000) { + multiply_by <<= 1; /* double value in each iteration */ + pdec <<= 1; /* correspondingly double pdec to cancel effect of double msel */ + cco_freq = input_freq * multiply_by; + } + selr = 0; + seli = (multiply_by & 0x3c) + 4; + selp = (multiply_by >> 1) + 1; + + if (pdec > 1) { + directo = 0; /* use post divider */ + pdec = pdec / 2; /* Account for minus 1 encoding */ + /* Translate P value */ + pdec = (pdec == 1) ? 0x62 : /* 1 * 2 */ + (pdec == 2) ? 0x42 : /* 2 * 2 */ + (pdec == 4) ? 0x02 : /* 4 * 2 */ + (pdec == 8) ? 0x0b : /* 8 * 2 */ + (pdec == 16) ? 0x11 : /* 16 * 2 */ + (pdec == 32) ? 0x08 : 0x08; /* 32 * 2 */ + } + + /* Only support values of 2 to 16 (to keep driver simple) */ + mdec = 0x7fff >> (16 - (multiply_by - 1)); + ndec = 0x202; /* pre divide by 2 (hardcoded) */ + + LPC_SYSCON->SYSPLLCTRL = SYS_PLL_BANDSEL | directo | (selr << SYSCON_SYSPLLCTRL_SELR_P) | + (seli << SYSCON_SYSPLLCTRL_SELI_P) | (selp << SYSCON_SYSPLLCTRL_SELP_P); + LPC_SYSCON->SYSPLLPDEC = pdec | (1 << 7); /* set Pdec value and assert preq */ + LPC_SYSCON->SYSPLLNDEC = ndec | (1 << 10); /* set Pdec value and assert preq */ + LPC_SYSCON->SYSPLLSSCTRL[0] = (1 << 18) | (1 << 17) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */ +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..e207af92ef0a601c60869265251487d06d37f938 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pll_5410x.h @@ -0,0 +1,305 @@ +/* + * @brief LPC5410X PLL 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 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 __PLL_5410X_H_ +#define __PLL_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PLL_5410X CHIP: LPC5410X PLL Driver + * @ingroup CHIP_5410X_DRIVERS + * The PLL in the LPC5410x is flexible, but can be complex to use. This driver + * provides functions to help setup and use the PLL in it's various supported + * modes.
+ * + * This driver does not alter PLL clock source or system clocks outside the + * PLL (like the main clock source) that may be referenced from the PLL. It + * may optionally setup system voltages, wait for PLL lock, and power cycle + * the PLL during setup based on setup flags. + * + * The driver works by first generating a PLL setup structure from a desired + * PLL configuration structure. The PLL setup structure is then passed to the + * PLL setup function to setup the PLL. In a user spplication, the PLL setup + * structure can be pre-populated with PLL setup data to avoid using the PLL + * configuration structure (or multiple PLL setup structures can be used to + * more dynamically control PLL output rate). + * + * How to use this driver
+ @verbatim + // Setup PLL configuration + PLL_CONFIG_T pllConfig = { + 75000000, // desiredRate = 75MHz + 0, // InputRate = 0Hz (not used) + 0 // No flags, function will determine best setup to get closest rate + }; + + // Get closest PLL setup to get the desired configuration + PLL_SETUP_T pllSetup; + uint32_t actualPllRate; + PLL_ERROR_T pllError; + pllError = Chip_Clock_SetupPLLData(&pllConfig, &pllSetup, &actualPllRate); + if (pllError != PLL_ERROR_SUCCESS) { + printf("PLL setup error #%x\r\n", (uint32_t) pllError); + while (1); + } + else { + printf("PLL config successful, actual config rate = %uHz\r\n", actualPllRate); + } + + // Make sure main system clock is not using PLL, as the PLL setup + // function will power off and optionally power on the PLL + Chip_Clock_SetMainClockSource(SYSCON_MAINCLKSRC_IRC); + + // Setup PLL source + Chip_Clock_SetSystemPLLSource(SYSCON_PLLCLKSRC_IRC); + + // Now to apply the configuration to the PLL + pllSetup.flags = PLL_SETUPFLAG_WAITLOCK; + Chip_Clock_SetupSystemPLLPrec(&pllSetup); + + // Switch main system clock to PLL + Chip_Clock_SetMainClockSource(SYSCON_MAINCLKSRC_PLLOUT); + @endverbatim + * + * @{ + */ + +/** + * Clock sources for system PLLs + */ +typedef enum CHIP_SYSCON_PLLCLKSRC { + SYSCON_PLLCLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCON_PLLCLKSRC_CLKIN, /*!< External clock input pin */ + SYSCON_PLLCLKSRC_WDTOSC, /*!< WDT oscillator */ + SYSCON_PLLCLKSRC_RTC, /*!< RTC 32KHz oscillator */ +} CHIP_SYSCON_PLLCLKSRC_T; + +/** + * @brief Set System PLL clock source + * @param src : Clock source for system PLL + * @return Nothing + * @note The PLL should be pwoered down prior to changing the source. + */ +STATIC INLINE void Chip_Clock_SetSystemPLLSource(CHIP_SYSCON_PLLCLKSRC_T src) +{ + LPC_SYSCON->SYSPLLCLKSEL = (uint32_t) src; +} + +/** + * @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 + * @param recompute : Forces a PLL rate recomputation if true + * @return System PLL output clock rate + * @note The PLL rate is cached in the driver in a variable as + * the rate computation function can take some time to perform. It + * is recommended to use 'false' with the 'recompute' parameter. + */ +uint32_t Chip_Clock_GetSystemPLLOutClockRate(bool recompute); + +/** + * @brief Enables and disables PLL bypass mode + * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass + * @return System PLL output clock rate + */ +void Chip_Clock_SetBypassPLL(bool bypass); + +/** + * @brief Check if PLL is locked or not + * @return true if the PLL is locked, false if not locked + */ +STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void) +{ + return (bool) ((LPC_SYSCON->SYSPLLSTAT & 1) != 0); +} + +/** @brief PLL configuration structure flags for 'flags' field + * These flags control how the PLL configuration function sets up the PLL setup structure.
+ * + * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the + * configuration structure must be assigned with the expected PLL frequency. If the + * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration + * function and the driver will determine the PLL rate from the currently selected + * PLL source. This flag might be used to configure the PLL input clock more accurately + * when using the WDT oscillator or a more dyanmic CLKIN source.
+ * + * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the + * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider + * are not used.
+ */ +#define PLL_CONFIGFLAG_USEINRATE (1 << 0) /*!< Flag to use InputRate in PLL configuration structure for setup */ +#define PLL_CONFIGFLAG_FORCENOFRACT (1 << 2) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or SS hardware */ + +/** @brief PLL Spread Spectrum (SS) Programmable modulation frequency + * See (MF) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum { + SS_MF_512 = (0 << 20), /*!< Nss = 512 (fm ˜ 3.9 - 7.8 kHz) */ + SS_MF_384 = (1 << 20), /*!< Nss ˜= 384 (fm ˜ 5.2 - 10.4 kHz) */ + SS_MF_256 = (2 << 20), /*!< Nss = 256 (fm ˜ 7.8 - 15.6 kHz) */ + SS_MF_128 = (3 << 20), /*!< Nss = 128 (fm ˜ 15.6 - 31.3 kHz) */ + SS_MF_64 = (4 << 20), /*!< Nss = 64 (fm ˜ 32.3 - 64.5 kHz) */ + SS_MF_32 = (5 << 20), /*!< Nss = 32 (fm ˜ 62.5- 125 kHz) */ + SS_MF_24 = (6 << 20), /*!< Nss ˜= 24 (fm ˜ 83.3- 166.6 kHz) */ + SS_MF_16 = (7 << 20) /*!< Nss = 16 (fm ˜ 125- 250 kHz) */ +} SS_PROGMODFM_T; + +/** @brief PLL Spread Spectrum (SS) Programmable frequency modulation depth + * See (MR) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum { + SS_MR_K0 = (0 << 23), /*!< k = 0 (no spread spectrum) */ + SS_MR_K1 = (1 << 23), /*!< k = 1 */ + SS_MR_K1_5 = (2 << 23), /*!< k = 1.5 */ + SS_MR_K2 = (3 << 23), /*!< k = 2 */ + SS_MR_K3 = (4 << 23), /*!< k = 3 */ + SS_MR_K4 = (5 << 23), /*!< k = 4 */ + SS_MR_K6 = (6 << 23), /*!< k = 6 */ + SS_MR_K8 = (7 << 23) /*!< k = 8 */ +} SS_PROGMODDP_T; + +/** @brief PLL Spread Spectrum (SS) Modulation waveform control + * See (MC) field in the SYSPLLSSCTRL1 register in the UM.
+ * Compensation for low pass filtering of the PLL to get a triangular + * modulation at the output of the PLL, giving a flat frequency spectrum. + */ +typedef enum { + SS_MC_NOC = (0 << 26), /*!< no compensation */ + SS_MC_RECC = (2 << 26), /*!< recommended setting */ + SS_MC_MAXC = (3 << 26), /*!< max. compensation */ +} SS_MODWVCTRL_T; + +/** @brief PLL configuration structure + * This structure can be used to configure the settings for a PLL + * setup structure. Fill in the desired configuration for the PLL + * and call the PLL setup function to fill in a PLL setup structure. + */ +typedef struct { + uint32_t desiredRate; /*!< Desired PLL rate in Hz */ + uint32_t InputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */ + uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */ + SS_PROGMODFM_T ss_mf; /*!< SS Programmable modulation frequency, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ + SS_PROGMODDP_T ss_mr; /*!< SS Programmable frequency modulation depth, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ + SS_MODWVCTRL_T ss_mc; /*!< SS Modulation waveform control, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ + bool mfDither; /*!< false for fixed modulation frequency or true for dithering, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ +} PLL_CONFIG_T; + +/** @brief PLL setup structure flags for 'flags' field + * These flags control how the PLL setup function sets up the PLL + */ +#define PLL_SETUPFLAG_POWERUP (1 << 0) /*!< Setup will power on the PLL after setup */ +#define PLL_SETUPFLAG_WAITLOCK (1 << 1) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */ +#define PLL_SETUPFLAG_ADGVOLT (1 << 2) /*!< Optimize system voltage for the new PLL rate */ + +/** @brief PLL setup structure + * This structure can be used to pre-build a PLL setup configuration + * at run-time and quickly set the PLL to the configuration. It can be + * populated with the PLL setup function. If powering up or waiting + * for PLL lock, the PLL input clock source should be configured prior + * to PLL setup. + */ +typedef struct { + uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */ + uint32_t SYSPLLCTRL; /*!< PLL control register */ + uint32_t SYSPLLNDEC; /*!< PLL NDEC register */ + uint32_t SYSPLLPDEC; /*!< PLL PDEC register */ + uint32_t SYSPLLSSCTRL[2]; /*!< PLL SSCTL registers */ +} PLL_SETUP_T; + +/** @brief PLL status definitions + */ +typedef enum { + PLL_ERROR_SUCCESS = 0, /*!< PLL operation was successful */ + PLL_ERROR_OUTPUT_TOO_LOW, /*!< PLL output rate request was too low */ + PLL_ERROR_OUTPUT_TOO_HIGH, /*!< PLL output rate request was too high */ + PLL_ERROR_INPUT_TOO_LOW, /*!< PLL input rate is too low */ + PLL_ERROR_INPUT_TOO_HIGH, /*!< PLL input rate is too high */ + PLL_ERROR_OUTSIDE_INTLIMIT /*!< Requested output rate isn't possible */ +} PLL_ERROR_T; + +/** + * @brief Return System PLL output clock rate from setup structure + * @param pSetup : Pointer to a PLL setup structure + * @return System PLL output clock rate the setup structure will generate + */ +uint32_t Chip_Clock_GetSystemPLLOutFromSetup(PLL_SETUP_T *pSetup); + +/** + * @brief Set PLL output based on the passed PLL setup data + * @param pControl : Pointer to populated PLL control structure to generate setup with + * @param pSetup : Pointer to PLL setup structure to be filled + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note Actual frequency for setup may vary from the desired frequency based on the + * accuracy of input clocks, rounding, non-fractional PLL mode, etc. + */ +PLL_ERROR_T Chip_Clock_SetupPLLData(PLL_CONFIG_T *pControl, PLL_SETUP_T *pSetup); + +/** + * @brief Set PLL output from PLL setup structure (precise frequency) + * @param pSetup : Pointer to populated PLL setup structure + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +PLL_ERROR_T Chip_Clock_SetupSystemPLLPrec(PLL_SETUP_T *pSetup); + +/** + * @brief Set PLL output based on the multiplier and input frequency + * @param multiply_by : multiplier + * @param input_freq : Clock input frequency of the PLL + * @return Nothing + * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this + * function does not disable or enable PLL power, wait for PLL lock, + * or adjust system voltages. These must be done in the application. + * The function will not alter any source clocks (ie, main systen clock) + * that may use the PLL, so these should be setup prior to and after + * exiting the function. + */ +void Chip_Clock_SetupSystemPLL(uint32_t multiply_by, uint32_t input_freq); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PLL_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pmu_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pmu_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..46eb9ffd3240d82073f236df1d1de2008623659c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/pmu_5410x.h @@ -0,0 +1,184 @@ +/* + * @brief LPC5410X Power Management declarations and functions + * + * @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 __PMU_5410X_H_ +#define __PMU_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PMU_5410X CHIP: LPC5410X Power Management declarations and functions + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief PMU register block structure + * @note Most of the PMU support is handled by the PMU library. + */ +typedef struct { + __I uint32_t RESERVED0[4]; + __I uint32_t RESERVED1[4]; + __I uint32_t RESERVED2[4]; + __I uint32_t RESERVED3[4]; + __I uint32_t RESERVED4; + __IO uint32_t BODCTRL; + __I uint32_t RESERVED5; + __I uint32_t RESERVED6; + __IO uint32_t DPDWAKESRC; +} LPC_PMU_T; + +/** + * Brown-out detector reset level + */ +typedef enum { + PMU_BODRSTLVL_0, /*!< Brown-out reset at ~1.5v */ + PMU_BODRSTLVL_1_50V = PMU_BODRSTLVL_0, + PMU_BODRSTLVL_1, /*!< Brown-out reset at ~1.85v */ + PMU_BODRSTLVL_1_85V = PMU_BODRSTLVL_1, + PMU_BODRSTLVL_2, /*!< Brown-out reset at ~2.0v */ + PMU_BODRSTLVL_2_00V = PMU_BODRSTLVL_2, + PMU_BODRSTLVL_3, /*!< Brown-out reset at ~2.3v */ + PMU_BODRSTLVL_2_30V = PMU_BODRSTLVL_3 +} CHIP_PMU_BODRSTLVL_T; + +/** + * Brown-out detector interrupt level + */ +typedef enum CHIP_PMU_BODRINTVAL { + PMU_BODINTVAL_LVL0, /*!< Brown-out interrupt at ~2.05v */ + PMU_BODINTVAL_2_05v = PMU_BODINTVAL_LVL0, + PMU_BODINTVAL_LVL1, /*!< Brown-out interrupt at ~2.45v */ + PMU_BODINTVAL_2_45v = PMU_BODINTVAL_LVL1, + PMU_BODINTVAL_LVL2, /*!< Brown-out interrupt at ~2.75v */ + PMU_BODINTVAL_2_75v = PMU_BODINTVAL_LVL2, + PMU_BODINTVAL_LVL3, /*!< Brown-out interrupt at ~3.05v */ + PMU_BODINTVAL_3_05v = PMU_BODINTVAL_LVL3 +} CHIP_PMU_BODRINTVAL_T; + +/** + * brown-out detection reset status (in BODCTRL register) + */ +#define PMU_BOD_RST (1 << 6) +/** + * brown-out detection interrupt status (in BODCTRL register) + */ +#define PMU_BOD_INT (1 << 7) + +/** + * @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_PMU_EnableBODReset() to re-enable. + */ +STATIC INLINE void Chip_PMU_SetBODLevels(CHIP_PMU_BODRSTLVL_T rstlvl, + CHIP_PMU_BODRINTVAL_T intlvl) +{ + LPC_PMU->BODCTRL = ((uint32_t) rstlvl) | (((uint32_t) intlvl) << 2); +} + +/** + * @brief Enable brown-out detection reset + * @return Nothing + */ +STATIC INLINE void Chip_PMU_EnableBODReset(void) +{ + LPC_PMU->BODCTRL |= (1 << 4); +} + +/** + * @brief Disable brown-out detection reset + * @return Nothing + */ +STATIC INLINE void Chip_PMU_DisableBODReset(void) +{ + LPC_PMU->BODCTRL &= ~(1 << 4); +} + +/** + * @brief Enable brown-out detection interrupt + * @return Nothing + */ +STATIC INLINE void Chip_PMU_EnableBODInt(void) +{ + LPC_PMU->BODCTRL |= (1 << 5); +} + +/** + * @brief Disable brown-out detection interrupt + * @return Nothing + */ +STATIC INLINE void Chip_PMU_DisableBODInt(void) +{ + LPC_PMU->BODCTRL &= ~(1 << 5); +} + +/** + * Deep power down reset sources + */ +#define PMU_DPDWU_RESET (1 << 0) /*!< Deep powerdown wakeup by reset pin */ +#define PMU_DPDWU_RTC (1 << 1) /*!< Deep powerdown wakeup by RTC */ +#define PMU_DPDWU_BODRESET (1 << 2) /*!< Deep powerdown wakeup by brown out reset*/ +#define PMU_DPDWU_BODINTR (1 << 3) /*!< Deep powerdown wakeup by brown out interrupt */ + +/** + * @brief Return wakeup sources from deep power down mode + * @return Deep power down mode wakeup sources + * @note Mask the return value with a PMU_DPDWU_* value to determine + * the wakeup source from deep power down. + */ +STATIC INLINE uint32_t Chip_PMU_GetDPDWUSource(void) +{ + return LPC_PMU->DPDWAKESRC; +} + +/** + * @brief Clear a deep power down mode wakeup source + * @param mask : Or'ed PMU_DPDWU_* values to clear + * @return Nothing + */ +STATIC INLINE void Chip_PMU_ClearDPDWUSource(uint32_t mask) +{ + LPC_PMU->DPDWAKESRC = mask; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PMU_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power.a b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power.a new file mode 100644 index 0000000000000000000000000000000000000000..0ac3c53ece8b960179276bb5c861cfe4a6197f98 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power.a differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power_m0.a b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power_m0.a new file mode 100644 index 0000000000000000000000000000000000000000..c6bcba184cf7650e9ebf97d99b0b7cb291420331 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/iar/lib_power_m0.a differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power.lib b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power.lib new file mode 100644 index 0000000000000000000000000000000000000000..d6271384a44b6e0a15a9e8320591e37bbeb6e916 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power.lib differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power_m0.lib b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power_m0.lib new file mode 100644 index 0000000000000000000000000000000000000000..7295fbb264280affb7bfbda76c6481843df296f0 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/keil/lib_power_m0.lib differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/lib_power.a b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/lib_power.a new file mode 100644 index 0000000000000000000000000000000000000000..f5064ec2ef3f71a60ae2a254947db8e2eab1a800 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/lib_power.a differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower.a b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower.a new file mode 100644 index 0000000000000000000000000000000000000000..f5064ec2ef3f71a60ae2a254947db8e2eab1a800 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower.a differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower_m0.a b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower_m0.a new file mode 100644 index 0000000000000000000000000000000000000000..f1e2dbc5ca27d6ee14a7867891216751b3c5b266 Binary files /dev/null and b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib/lpcxpresso/libpower_m0.a differ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..52e902c6eddd6884014c053646c1b15ab76ce366 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/power_lib_5410x.h @@ -0,0 +1,167 @@ +/* + * @brief LPC5410x Power library functions + * + * @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 __POWER_LIB_5410X_H_ +#define __POWER_LIB_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup POWER_LIBRARY_5410X CHIP: LPC5410X Power LIBRARY functions + * The power library provides functions to control system power usage and + * place the device into low power modes.
+ * + * Clock shutdown in sleep and power down modes
+ * When using the Chip_POWER_EnterPowerMode() function, system clocks are + * shutdown based on the selected sleep or power down mode and the device + * version being used. The following list details which clocks are shut down + * in which modes for which device versions. You can keep a clock enabled + * for a sleep or power down mode by enabling it in the 'peripheral_ctrl' + * field in the Chip_POWER_EnterPowerMode() function.
+ * + * Mode: Sleep
+ * No clocks are disabled for any chip version.
+ * + * Mode: Deep sleep
+ * SYSCON_PDRUNCFG_PD_IRC_OSC
+ * SYSCON_PDRUNCFG_PD_IRC
+ * SYSCON_PDRUNCFG_PD_FLASH (v17.1 and later only)
+ * SYSCON_PDRUNCFG_PD_BOD_INTR
+ * SYSCON_PDRUNCFG_PD_ADC0
+ * SYSCON_PDRUNCFG_PD_ROM
+ * SYSCON_PDRUNCFG_PD_VDDA_ENA
+ * SYSCON_PDRUNCFG_PD_SYS_PLL
+ * SYSCON_PDRUNCFG_PD_VREFP
+ * + * Mode: Power down
+ * SYSCON_PDRUNCFG_PD_IRC_OSC
+ * SYSCON_PDRUNCFG_PD_IRC
+ * SYSCON_PDRUNCFG_PD_FLASH (v17.1 and later only)
+ * SYSCON_PDRUNCFG_PD_BOD_RST
+ * SYSCON_PDRUNCFG_PD_BOD_INTR
+ * SYSCON_PDRUNCFG_PD_ADC0
+ * SYSCON_PDRUNCFG_PD_SRAM0B
+ * SYSCON_PDRUNCFG_PD_SRAM1
+ * SYSCON_PDRUNCFG_PD_SRAM2
+ * SYSCON_PDRUNCFG_PD_ROM
+ * SYSCON_PDRUNCFG_PD_VDDA_ENA
+ * SYSCON_PDRUNCFG_PD_WDT_OSC
+ * SYSCON_PDRUNCFG_PD_SYS_PLL
+ * SYSCON_PDRUNCFG_PD_VREFP
+ * SYSCON_PDRUNCFG_PD_32K_OSC
+ * + * Mode: Deep power down
+ * All clocks are disabled for all chip versions.
+ * + * If you are using a peripheral was a wakeup source for a power down mode, + * it needs to be kept active with the call to Chip_POWER_EnterPowerMode(). For + * example, if you are using the RTC to wake the system up from power down mode, + * the 32KHz RTC oscillator needs to remain active, so the power down call would + * look like this:
+ * Chip_POWER_EnterPowerMode(POWER_POWER_DOWN, SYSCON_PDRUNCFG_PD_32K_OSC);
+ * If your application uses internal RAM beyond the first 8K, you will also need + * to prevent power down of the IRAM like this:
+ * Chip_POWER_EnterPowerMode(POWER_POWER_DOWN, (SYSCON_PDRUNCFG_PD_32K_OSC | SYSCON_PDRUNCFG_PD_SRAM0A));
+ * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief Sets up the System PLL given the PLL input frequency and feedback multiplier + * @param multiply_by : PLL multiplier, minimum of 1, maximum of 16 + * @param input_freq : Input frequency into the PLL + * @return LPC_OK on success, or an error code (see error.h) + */ +uint32_t Chip_POWER_SetPLL(uint32_t multiply_by, uint32_t input_freq); + +/** + * @brief Set optimal system voltage based on passed system frequency + * @param mode : Power mode + * @param desired_freq : System (CPU) frequency + * @return LPC_OK on success, or an error code (see error.h) + * @note This function will adjust the system voltages to the lowest + * levels that will support the passed mode and CPU frequency. + */ +uint32_t Chip_POWER_SetVoltage(PERF_MODE_T mode, uint32_t desired_freq); + +/** + * @brief Enters the selected power state + * @param mode : Power mode + * @param peripheral_ctrl : Peripherals that will remain powered up in the power state + * @return Nothing + * @note The 'peripheral_ctrl' field is a bitmask of bits from the + * PDRUNCFG register (SYSCON_PDRUNCFG_PD_*) that describe which + * peripherals can wake up the chip from the power state. These + * peripherals are not powered down during the power state.
+ */ +void Chip_POWER_EnterPowerMode(POWER_MODE_T mode, uint32_t peripheral_ctrl); + +/* ROM versions */ +#define LPC5410X_ROMVER_0 (0x1100) +#define LPC5410X_ROMVER_1 (0x1101) +#define LPC5410X_ROMVER_2 (0x1102) + +/** + * @brief Fast powerdown for IRAM based applications + * @param peripheral_ctrl : Peripherals that will remain powered up in the power down state + * @return Nothing + * @note The 'peripheral_ctrl' field is a bitmask of bits from the + * PDRUNCFG register (SYSCON_PDRUNCFG_PD_*) that describe which + * peripherals can wake up the chip from the power state. These + * peripherals are not powered down during the power state.
+ * This function should only be used when not executing code in FLASH. + * It will power down FLASH and leave it powered down on exit, so all + * code should be placed in IRAM prior to calling. It provides a quicker + * wakeup response than the default powerdown function + * (Chip_POWER_EnterPowerMode(POWER_POWER_DOWN, ...)). + */ +void Chip_POWER_EnterPowerModeIramOnly(uint32_t peripheral_ctrl); + +/** + * @brief Return ROM version + * @return ROM version + * @note Will return one of the following version numbers:
+ * (0x1100) for v17.0 ROMs.
+ * (0x1101) for v17.1 ROMs.
+ * (0x1102) for v17.2 ROMs.
+ */ +uint32_t Chip_POWER_GetROMVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __POWER_LIB_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..e9aab5924e299b1ba3ebcec096a81bc0257031cd --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.c @@ -0,0 +1,105 @@ +/* + * @brief LPC5410X RITimer chip 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the RIT */ +void Chip_RIT_Init(LPC_RITIMER_T *pRITimer) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_RIT); + Chip_SYSCON_PeriphReset(RESET_RIT); + + /* Default is timer disabled */ + pRITimer->CTRL = 0x0; +} + +/* DeInitialize the RIT */ +void Chip_RIT_DeInit(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL = 0x0; + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_RIT); +} + +/* Set timer interval value */ +void Chip_RIT_SetTimerInterval(LPC_RITIMER_T *pRITimer, uint32_t time_interval) +{ + uint32_t cmp_value; + + /* Determine aapproximate compare value based on clock rate and passed interval */ + cmp_value = (Chip_Clock_GetMainClockRate() / 1000) * time_interval; + + /* Set timer compare value */ + Chip_RIT_SetCOMPVAL(pRITimer, cmp_value); +} + +/* Set timer interval value (48-bit) */ +void Chip_RIT_SetTimerInterval64(LPC_RITIMER_T *pRITimer, uint64_t time_interval) +{ + uint64_t cmp_value; + + /* Determine aapproximate compare value based on clock rate and passed interval */ + cmp_value = (uint64_t) Chip_Clock_GetMainClockRate() / 1000; + cmp_value = cmp_value * time_interval; + + /* Set timer compare value */ + Chip_RIT_SetCOMPVAL64(pRITimer, cmp_value); +} + +/* Check whether interrupt is pending */ +IntStatus Chip_RIT_GetIntStatus(LPC_RITIMER_T *pRITimer) +{ + uint8_t result; + + if ((pRITimer->CTRL & RIT_CTRL_INT) == 1) { + result = SET; + } + else { + return RESET; + } + + return (IntStatus) result; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..a5232ef1d8c77358f972f482c048766b41284cca --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/ritimer_5410x.h @@ -0,0 +1,249 @@ +/* + * @brief LPC5410x RITimer 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 __RITIMER_5410X_H_ +#define __RITIMER_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup RITIMER_5410X CHIP: LPC5410x Repetitive Interrupt Timer driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief Repetitive Interrupt Timer register block structure + */ +typedef struct { /*!< RITIMER Structure */ + __IO uint32_t COMPVAL; /*!< Compare register */ + __IO uint32_t MASK; /*!< Mask register */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t COUNTER; /*!< 32-bit counter */ + __IO uint32_t COMPVAL_H; /*!< Compare register, upper 16-bits */ + __IO uint32_t MASK_H; /*!< Compare register, upper 16-bits */ + __I uint32_t reserved; + __IO uint32_t COUNTER_H; /*!< Counter register, upper 16-bits */ +} LPC_RITIMER_T; + +/* + * @brief RITIMER register support bitfields and mask + */ + +/* + * RIT control register + */ +/** Set by H/W when the counter value equals the masked compare value */ +#define RIT_CTRL_INT ((uint32_t) (1)) +/** Set timer enable clear to 0 when the counter value equals the masked compare value */ +#define RIT_CTRL_ENCLR ((uint32_t) _BIT(1)) +/** Set timer enable on debug */ +#define RIT_CTRL_ENBR ((uint32_t) _BIT(2)) +/** Set timer enable */ +#define RIT_CTRL_TEN ((uint32_t) _BIT(3)) + +/** + * @brief Initialize the RIT + * @param pRITimer : RITimer peripheral selected + * @return None + */ +void Chip_RIT_Init(LPC_RITIMER_T *pRITimer); + +/** + * @brief Shutdown the RIT + * @param pRITimer : RITimer peripheral selected + * @return None + */ +void Chip_RIT_DeInit(LPC_RITIMER_T *pRITimer); + +/** + * @brief Enable Timer + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_Enable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL |= RIT_CTRL_TEN; +} + +/** + * @brief Disable Timer + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_Disable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL &= ~RIT_CTRL_TEN; +} + +/** + * @brief Enable timer debug + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_DebugEnable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL |= RIT_CTRL_ENBR; +} + +/** + * @brief Disable timer debug + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_DebugDisable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL &= ~RIT_CTRL_ENBR; +} + +/** + * @brief Enable clear on compare match + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_CompClearEnable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL |= RIT_CTRL_ENCLR; +} + +/** + * @brief Disable clear on compare match + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_CompClearDisable(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL &= ~RIT_CTRL_ENCLR; +} + +/** + * @brief Check whether interrupt flag is set or not + * @param pRITimer : RITimer peripheral selected + * @return Current interrupt status, either ET or UNSET + */ +IntStatus Chip_RIT_GetIntStatus(LPC_RITIMER_T *pRITimer); + +/** + * @brief Set a tick value for the interrupt to time out + * @param pRITimer : RITimer peripheral selected + * @param val : value (in ticks) of the interrupt to be set + * @return None + */ +STATIC INLINE void Chip_RIT_SetCOMPVAL(LPC_RITIMER_T *pRITimer, uint32_t val) +{ + pRITimer->COMPVAL = val; + pRITimer->COMPVAL_H = 0; +} + +/** + * @brief Set a tick value for the interrupt to time out (48-bits) + * @param pRITimer : RITimer peripheral selected + * @param val : value (in ticks) of the interrupt to be set, 48-bits max + * @return None + */ +STATIC INLINE void Chip_RIT_SetCOMPVAL64(LPC_RITIMER_T *pRITimer, uint64_t val) +{ + pRITimer->COMPVAL = (uint32_t) (val & 0xFFFFFFFF); + pRITimer->COMPVAL_H = (uint32_t) ((val >> 32) & 0xFFFF); +} + +/** + * @brief Enables or clears the RIT or interrupt + * @param pRITimer : RITimer peripheral selected + * @param val : RIT to be set, one or more RIT_CTRL_* values + * @return None + */ +STATIC INLINE void Chip_RIT_EnableCTRL(LPC_RITIMER_T *pRITimer, uint32_t val) +{ + pRITimer->CTRL |= val; +} + +/** + * @brief Clears the RIT interrupt + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_ClearInt(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL |= RIT_CTRL_INT; +} + +/** + * @brief Returns the current RIT Counter value + * @param pRITimer : RITimer peripheral selected + * @return the current timer counter value + */ +STATIC INLINE uint32_t Chip_RIT_GetCounter(LPC_RITIMER_T *pRITimer) +{ + return pRITimer->COUNTER; +} + +/** + * @brief Returns the current RIT Counter value (48-bit) + * @param pRITimer : RITimer peripheral selected + * @return the current timer counter value + */ +STATIC INLINE uint64_t Chip_RIT_GetCounter64(LPC_RITIMER_T *pRITimer) +{ + uint64_t retVal; + + retVal = (uint64_t) pRITimer->COUNTER; + retVal = retVal | (((uint64_t) pRITimer->COUNTER_H) << 32); + + return retVal; +} + +/** + * @brief Set timer interval value + * @param pRITimer : RITimer peripheral selected + * @param time_interval : timer interval value (ms) + * @return None + */ +void Chip_RIT_SetTimerInterval(LPC_RITIMER_T *pRITimer, uint32_t time_interval); + +/** + * @brief Set timer interval value (48-bit) + * @param pRITimer : RITimer peripheral selected + * @param time_interval : timer interval value (ms) + * @return None + */ +void Chip_RIT_SetTimerInterval64(LPC_RITIMER_T *pRITimer, uint64_t time_interval); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RITIMER_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rom_pwr_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rom_pwr_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..c6169f81fabcdbc0766ec021e8c5a4bfdf767fcd --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rom_pwr_5410x.h @@ -0,0 +1,77 @@ +/* + * @brief LPC5410X Power ROM API declarations and functions + * + * @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 __ROM_PWR_5410X_H_ +#define __ROM_PWR_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PWRD_5410X CHIP: LPC5410X Power ROM API declarations and functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/* 'mode' input values to set_voltage ROM function */ +typedef enum { + POWER_LOW_POWER_MODE = 0, + POWER_BALANCED_MODE, + POWER_HIGH_PERFORMANCE +} PERF_MODE_T; + +/* 'mode' input values to power_mode_configure ROM function */ +typedef enum { + POWER_SLEEP = 0, + POWER_DEEP_SLEEP, + POWER_POWER_DOWN, + POWER_DEEP_POWER_DOWN +} POWER_MODE_T; + +/** @brief Power ROM indirect function structure + * Do not use these functions as direct calls to ROM. Instead, use the + * wrapper functions provided by the Power library (power_lib_5410x.h) + */ +typedef struct { + uint32_t (*set_pll)(uint32_t multiply_by, uint32_t input_freq); + uint32_t (*set_voltage)(uint32_t mode, uint32_t desired_freq); + void (*power_mode_configure)(uint32_t mode, uint32_t peripheral_ctrl); +} PWRD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_PWR_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..e173bd4fb46eb8f7b654e6fd7066c4c7c0c91d30 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_5410x.h @@ -0,0 +1,139 @@ +/* + * @brief LPC5410X ROM API declarations and functions + * + * @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 __ROMAPI_5410X_H_ +#define __ROMAPI_5410X_H_ + +#include +#include "iap.h" +#include "error.h" +#include "cmsis.h" + +/* v1 ROM driver APIs */ +#include "rom_pwr_5410x.h" + +/* v2 ROM driver APIs */ +#include "romapi_adc.h" +#include "romapi_dma.h" +#include "romapi_i2cm.h" +#include "romapi_i2cmon.h" +#include "romapi_i2cs.h" +#include "romapi_spim.h" +#include "romapi_spis.h" +#include "romapi_uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_5410X CHIP: LPC5410X ROM API declarations and functions + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief High level ROM API structure + */ +typedef struct { + const uint32_t reserved_usb; /*!< Reserved */ + const uint32_t reserved_clib; /*!< Reserved */ + const uint32_t reserved_can; /*!< Reserved */ + const PWRD_API_T *pPWRD; /*!< Power API function table base address */ + const uint32_t reserved_div; /*!< Reserved */ + const uint32_t reserved_i2cd; /*!< Reserved */ + const uint32_t reserved_dmad; /*!< Reserved */ + const uint32_t reserved_spid; /*!< Reserved */ + const uint32_t reserved_adcd; /*!< Reserved */ + const uint32_t reserved_uartd; /*!< Reserved */ + const uint32_t reserved_vfifo; /*!< Reserved */ + const uint32_t reserved_usart; /*!< Reserved */ + /* v2 drivers - only present in some LPC5410x devices */ + const ROM_I2CMD_API_T *pI2CMD; /*!< v2 I2C master only driver API function table base address */ + const ROM_I2CSD_API_T *pI2CSD; /*!< v2 I2C slave only driver API function table base address */ + const ROM_I2CMOND_API_T *pI2CMOND; /*!< v2 I2C bus monitor driver API function table base address */ + const ROM_SPIMD_API_T *pSPIMD; /*!< v2 SPI master only driver API function table base address */ + const ROM_SPISD_API_T *pSPISD; /*!< v2 SPI slave only driver API function table base address */ + const ROM_DMAALTD_API_T *pDMAALT; /*!< v2 abstract DMA driver API function table base address */ + const ROM_ADC_API_T *pADCALT; /*!< v2 ADC driver API function table base address */ + const ROM_UART_API_T *pUARTALT; /*!< v2 UART driver API function table base address */ +} LPC_ROM_API_T; + +/* Pointer to ROM API function address */ +#define LPC_ROM_API_BASE_LOC 0x03000200UL +#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 v2 I2C master peripheral driver functions in ROM */ +#define ROMAPI_I2CM_API ((LPC_ROM_API)->pI2CMD) + +/* Pointer to v2 I2C master peripheral driver functions in ROM */ +#define ROMAPI_I2CMON_API ((LPC_ROM_API)->pI2CMOND) + +/* Pointer to v2 I2C slave peripheral driver functions in ROM */ +#define ROMAPI_I2CS_API ((LPC_ROM_API)->pI2CSD) + +/* Pointer to v2 SPI master peripheral driver functions in ROM */ +#define ROMAPI_SPIM_API ((LPC_ROM_API)->pSPIMD) + +/* Pointer to v2 SPI slave peripheral driver functions in ROM */ +#define ROMAPI_SPIS_API ((LPC_ROM_API)->pSPISD) + +/* Pointer to v2 DMA controller driver functions in ROM */ +#define ROMAPI_DMAALT_API ((LPC_ROM_API)->pDMAALT) + +/* Pointer to v2 ADC driver functions in ROM */ +#define ROMAPI_ADC_API ((LPC_ROM_API)->pADCALT) + +/* Pointer to v2 UART controller driver functions in ROM */ +#define ROMAPI_UART_API ((LPC_ROM_API)->pUARTALT) + +/* Pointer to ROM IAP entry functions */ +#define IAP_ENTRY_LOCATION 0x03000205 + +/** + * @brief LPC5410x IAP_ENTRY API function type + */ +static INLINE void iap_entry(unsigned int cmd_param[5], unsigned int status_result[4]) +{ + ((IAP_ENTRY_T) IAP_ENTRY_LOCATION)(cmd_param, status_result); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..c07ee4cbbc775f46786f96b5c7f30ac76ed3dab3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.c @@ -0,0 +1,160 @@ +/* + * @brief ADC ROM API declarations and functions + * These are the public ROM APIs and functions of the ADC ROM + * 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 "romapi_5410x.h" + +/* Get memory size in bytes needed for ADC driver context */ +uint32_t ROM_ADC_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->GetMemSize(); +#else + return adcrom_api.GetMemSize(); +#endif +} + +/* Initialize the ADC ROM driver */ +ADC_HANDLE_T ROM_ADC_Init(void *pMem, uint32_t baseAddr, void *pUserData) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->Init(pMem, baseAddr, pUserData); +#else + return adcrom_api.Init(pMem, baseAddr, pUserData); +#endif +} + +/* Configure the ADC peripheral */ +ErrorCode_t ROM_ADC_Configure(ADC_HANDLE_T hADC, const ADC_CFG_T *pCfg) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->Configure(hADC, pCfg); +#else + return adcrom_api.Configure(hADC, pCfg); +#endif +} + +/* Calibrate the ADC */ +ErrorCode_t ROM_ADC_Calibrate(ADC_HANDLE_T hADC, uint32_t sysclk_freq) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->Calibrate(hADC, sysclk_freq); +#else + return adcrom_api.Calibrate(hADC, sysclk_freq); +#endif +} + +/* Start the conversion on given SEQ */ +ErrorCode_t ROM_ADC_StartConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex, void *pBuf, size_t bufCount) +{ +#if defined(ROMDRIVERSV2_PRESENT) + /* Correct index adjust bug */ + uint32_t *ptr = &((uint32_t *)hADC)[9 + seqIndex * 6]; + if (*ptr != 2) *(ptr - 1) = 0; + + return ROMAPI_ADC_API->StartConversion(hADC, seqIndex, pBuf, bufCount); +#else + return adcrom_api.StartConversion(hADC, seqIndex, pBuf, bufCount); +#endif +} + +/* ADC Event handler */ +ErrorCode_t ROM_ADC_Handler(ADC_HANDLE_T hADC, ADC_HEVENT_T hEvent) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->Handler(hADC, hEvent); +#else + return adcrom_api.Handler(hADC, hEvent); +#endif +} + +/* ADC Callback register */ +ErrorCode_t ROM_ADC_RegisterCB(ADC_HANDLE_T hADC, ADC_CBINDEX_T cbIndex, void (*pCbFunc)(ADC_HANDLE_T, + ADC_CBINDEX_T, + void *)) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->RegisterCB(hADC, cbIndex, pCbFunc); +#else + return adcrom_api.RegisterCB(hADC, cbIndex, pCbFunc); +#endif +} + +/* Set Threshold register values */ +void ROM_ADC_SetThreshold(ADC_HANDLE_T hADC, uint32_t valThr0, uint32_t valThr1) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_ADC_API->SetThreshold(hADC, valThr0, valThr1); +#else + adcrom_api.SetThreshold(hADC, valThr0, valThr1); +#endif +} + +/* Configure ADC channel */ +ErrorCode_t ROM_ADC_ConfigureCh(ADC_HANDLE_T hADC, uint32_t chanNum, uint32_t chanOpts) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->ConfigureCh(hADC, chanNum, chanOpts); +#else + return adcrom_api.ConfigureCh(hADC, chanNum, chanOpts); +#endif +} + +/* Stop conversion of Analog samples */ +ErrorCode_t ROM_ADC_StopConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->StopConversion(hADC, seqIndex); +#else + return adcrom_api.StopConversion(hADC, seqIndex); +#endif +} + +/* Generate a software trigger */ +ErrorCode_t ROM_ADC_SwTrigger(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->SwTrigger(hADC, seqIndex); +#else + return adcrom_api.SwTrigger(hADC, seqIndex); +#endif +} + +/* Get Current verion of the driver */ +uint16_t ROM_ADC_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_ADC_API->GetDriverVersion(); +#else + return adcrom_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..e648fb19747988b64b596fe3914ffbe0ce3110c4 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_adc.h @@ -0,0 +1,184 @@ +/* + * @brief ADC ROM API declarations and functions + * + * @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 __ROMAPI_ADC_H_ +#define __ROMAPI_ADC_H_ + +#include "hw_adc_rom_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_ADC_WRAPPER CHIP: ADC ROM Driver wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for ADC driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_ADC_GetMemSize(void); + +/** + * @brief Initialize ADC ROM Driver + * @param pMem : Pointer to memory area for driver context + * @param baseAddr : Base address of the ADC peripheral + * @param pUserData : Pointer to User Data + * @return Pointer to the device context handle or NULL on alignment failure + * @note Parameter @a pMem must be a pointer to word aligned memory + * if the pointer is not word aligned (4-Byte) the function returns + * NULL. + */ +ADC_HANDLE_T ROM_ADC_Init(void *pMem, uint32_t baseAddr, void *pUserData); + +/** + * @brief Configure the ADC peripheral + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param pCfg : Pointer to configuration structure #ADC_CFG_T + * @return Always returns LPC_OK + */ +ErrorCode_t ROM_ADC_Configure(ADC_HANDLE_T hADC, const ADC_CFG_T *pCfg); + +/** + * @brief Calibrate ADC upon startup or wakeup after powerdown + * @pre ADC must be Initialized and Configured + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param sysclk_freq : Frequency of the system + * @return Result of calibrarion operation + * @retval LPC_OK Calibration is successful + * @retval ERR_ADC_NO_POWER Unable to powerup ADC + * @retval ERR_TIME_OUT Calibration operation timed-out + */ +ErrorCode_t ROM_ADC_Calibrate(ADC_HANDLE_T hADC, uint32_t sysclk_freq); + +/** + * @brief Start the ADC peripheral + * @pre ADC must be properly initialized, Configured and Calibrated + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param seqIndex : Index of the sequence to start must be one of #ADC_SEQ_A or #ADC_SEQ_B + * @param pBuf : Pointer to buffer (see note below) + * @param szBuf : Size of buffer (see note below) + * @return Result of the start operation + * @retval LPC_OK Successfully started ADC sampling on given sequence or + * given buffer is queued successfully (when called from #ADC_BUFFER_DONE + * callback handler) + * @retval ERR_ADC_INVALID_SEQUENCE Parameter @a seqIndex is not one of #ADC_SEQ_A or #ADC_SEQ_B + * @retval ERR_BUSY Already a buffer is active and swap buffer is also configured + * @note The size of the buffer must be M x N where M is the number of channels enabled in + * sequence @a seqIndex, and N is the number of samples to be converted. + * The buffer provided by @a pBuf must be of size M x N x sizeof(uint16_t) bytes(for non-DMA). + * Assume that channels 1, 3, 4, 8 are enabled in sequence @a seqIndex and number of + * samples to be collected is N, the buffer will be filled with DATA_1[0], DATA_3[0], + * DATA_4[0], DATA_8[0], ... , DATA_1[N], DATA_3[N], DATA_4[N], DATA_8[N], note + * that the order in which the channels are enabled does not matter they will always be + * filled up in ascending order. + */ +ErrorCode_t ROM_ADC_StartConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex, void *pBuf, size_t szBuf); + +/** + * @brief Handler to handle ADC events + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param hEvent : Type of the event + * @return Event handling results + * @retval LPC_OK Event successfully handled + * @retval ERR_ADC_INVALID_SEQUENCE Event is not for the given sequence + * @retval ERR_FAILED Internal ADC error (Channel enabled but no data available) + * @retval ERR_ADC_PARAM Invaild event parameter for @a hEvent + */ +ErrorCode_t ROM_ADC_Handler(ADC_HANDLE_T hADC, ADC_HEVENT_T hEvent); + +/** + * @brief Registers a callback function associated with an event + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param cbIndex : Index of the call-back function (Associated with an event) + * @param pCbFunc : Pointer to callback function + * @return Success or failure + * @retval LPC_OK Callback successfully registered + * @retval ERR_ADC_PARAM Invaild event parameter for @a cbIndex + */ +ErrorCode_t ROM_ADC_RegisterCB(ADC_HANDLE_T hADC, ADC_CBINDEX_T cbIndex, void (*pCbFunc)(ADC_HANDLE_T, + ADC_CBINDEX_T, + void *)); + +/** + * @brief Setup high and low threshold values for threshold 0, 1 + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param valThr0 : Threshold 0 value (bits 31-16 has high value, bits 15-0 has low value) + * @param valThr1 : Threshold 1 value (bits 31-16 has high value, bits 15-0 has low value) + * @return Nothing + */ +void ROM_ADC_SetThreshold(ADC_HANDLE_T hADC, uint32_t valThr0, uint32_t valThr1); + +/** + * @brief Configure a single channel + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param chanNum : Channel number + * @param chanOpts : Options for the channel + * @return LPC_OK on success, ERR_ADC_PARAM if @a chanNum is invalid + */ +ErrorCode_t ROM_ADC_ConfigureCh(ADC_HANDLE_T hADC, uint32_t chanNum, uint32_t chanOpts); + +/** + * @brief Stop the conversion in progress + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param seqIndex : Sequence that needs to be stopped + * @return LPC_OK on success, ERR_ADC_INVALID_SEQUENCE if @a seqIndex is invalid + */ +ErrorCode_t ROM_ADC_StopConversion(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex); + +/** + * @brief Generate software trigger for given sequence + * @param hADC : Handle to ADC obtained using ROM_ADC_Init() + * @param seqIndex : Sequence that needs to be triggered + * @return LPC_OK on success, ERR_ADC_INVALID_SEQUENCE if @a seqIndex is invalid + */ +ErrorCode_t ROM_ADC_SwTrigger(ADC_HANDLE_T hADC, ADC_SEQ_INDEX_T seqIndex); + +/** + * @brief Return the ADC ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_ADC_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_ADC_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..7c9450fdfd5d7c90f706fd836f6b7531d99e67fd --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.c @@ -0,0 +1,232 @@ +/* + * @brief DMA master ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for DMA controller driver context */ +uint32_t ROM_DMA_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->GetMemSize(); +#else + return dmaalt_api.GetMemSize(); +#endif +} + +/* Initialize DMA controller */ +ROM_DMA_HANDLE_T ROM_DMA_Init(void *mem, ROM_DMA_INIT_T *pInit) +{ + /* Verify SRAMBASE alginemnt is at least MINDMATABLEALIGN bytes */ + if (((uint32_t) pInit->sramBase & (MINDMATABLEALIGN - 1)) != 0) { + return NULL; + } + +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->Init(mem, pInit); +#else + return dmaalt_api.Init(mem, pInit); +#endif +} + +/* Configures a DMA channel */ +ErrorCode_t ROM_DMA_SetupChannel(ROM_DMA_HANDLE_T pHandle, ROM_DMA_CHAN_CFG_T *pCfg, uint8_t dmaCh) +{ + if (dmaCh >= NUMDMACHANNELS) { + return ERR_DMA_CHANNEL_NUMBER; + } + +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->SetupChannel(pHandle, pCfg, dmaCh); +#else + return dmaalt_api.SetupChannel(pHandle, pCfg, dmaCh); +#endif +} + +/* Initializes a transfer descriptor queue for a channel */ +ErrorCode_t ROM_DMA_InitQueue(ROM_DMA_HANDLE_T pHandle, uint8_t dmaCh, ROM_DMA_QUEUE_T *pQueue) +{ + if (dmaCh >= NUMDMACHANNELS) { + return ERR_DMA_CHANNEL_NUMBER; + } + +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->InitQueue(pHandle, dmaCh, pQueue); +#else + return dmaalt_api.InitQueue(pHandle, dmaCh, pQueue); +#endif +} + +/* Registers an DMA controller callback for a queue */ +void ROM_DMA_RegisterQueueCallback(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, uint32_t cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->RegisterQueueCallback(pHandle, pQueue, cbIndex, pCB); +#else + dmaalt_api.RegisterQueueCallback(pHandle, pQueue, cbIndex, pCB); +#endif +} + +/* Builds a transfer descriptor chain from the passed settings */ +ErrorCode_t ROM_DMA_BuildDescriptorChain(ROM_DMA_HANDLE_T pHandle, + ROM_DMA_XFERDESC_CFG_T *pXferCfg, + ROM_DMA_DESC_T *pDesc, + ROM_DMA_DESC_T *pDescPrev) +{ + if (pXferCfg->dmaCh >= NUMDMACHANNELS) { + return ERR_DMA_CHANNEL_NUMBER; + } + +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->BuildDescriptorChain(pHandle, pXferCfg, pDesc, pDescPrev); +#else + return dmaalt_api.BuildDescriptorChain(pHandle, pXferCfg, pDesc, pDescPrev); +#endif +} + +/* Returns the number of items transferred on the last descriptor chain (spent status only) */ +uint32_t ROM_DMA_GetTransferCount(ROM_DMA_HANDLE_T pHandle, ROM_DMA_DESC_T *pDesc) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->GetTransferCount(pHandle, pDesc); +#else + return dmaalt_api.GetTransferCount(pHandle, pDesc); +#endif +} + +/* Unstalls a descriptor chain that has been setup using the stallDesc option */ +void ROM_DMA_UnstallDescriptorChain(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->UnstallDescriptorChain(pHandle, pQueue); +#else + dmaalt_api.UnstallDescriptorChain(pHandle, pQueue); +#endif +} + +/* Queues a transfer descriptor chain */ +void ROM_DMA_QueueDescriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, ROM_DMA_DESC_T *pDescChainHead) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->QueueDescriptor(pHandle, pQueue, pDescChainHead); +#else + dmaalt_api.QueueDescriptor(pHandle, pQueue, pDescChainHead); +#endif +} + +/* Returns current status of next descriptor to be popped from the queue */ +ROM_DMA_DESC_STS_T ROM_DMA_GetQueuePopDescriptorStatus(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->GetQueuePopDescriptorStatus(pHandle, pQueue); +#else + return dmaalt_api.GetQueuePopDescriptorStatus(pHandle, pQueue); +#endif +} + +/* Pops (unqueues) an expired transfer descriptor from the queue - expired descriptors are in spent, error, or abort states */ +ROM_DMA_DESC_T *ROM_DMA_UnQueueDescriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->UnQueueDescriptor(pHandle, pQueue); +#else + return dmaalt_api.UnQueueDescriptor(pHandle, pQueue); +#endif +} + +/* Starts or restarts a queue at the next descriptor chain */ +ErrorCode_t ROM_DMA_StartQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->StartQueue(pHandle, pQueue); +#else + return dmaalt_api.StartQueue(pHandle, pQueue); +#endif +} + +/* Stops DMA and aborts current descriptor chain being processed in queue */ +ErrorCode_t ROM_DMA_StopQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->StopQueue(pHandle, pQueue); +#else + return dmaalt_api.StopQueue(pHandle, pQueue); +#endif +} + +/* Stops DMA and completely flushes a transfer queue, queue is completely reset */ +void ROM_DMA_FlushQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->FlushQueue(pHandle, pQueue); +#else + dmaalt_api.FlushQueue(pHandle, pQueue); +#endif +} + +/* Returns the current queue state (ROM_DMA_QUEUE_STATES_T) */ +uint8_t ROM_DMA_GetQueueState(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->GetQueueState(pHandle, pQueue); +#else + return dmaalt_api.GetQueueState(pHandle, pQueue); +#endif +} + +/* Forces a DMA transfer to trigger */ +void ROM_DMA_ForceTrigger(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->ForceTrigger(pHandle, pQueue); +#else + dmaalt_api.ForceTrigger(pHandle, pQueue); +#endif +} + +/* DMA controller (interrupt) handler */ +void ROM_DMA_DMAHandler(ROM_DMA_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_DMAALT_API->DMAHandler(pHandle); +#else + dmaalt_api.DMAHandler(pHandle); +#endif +} + +/* Return the DMA controller ROM driver version */ +uint16_t ROM_DMA_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_DMAALT_API->GetDriverVersion(); +#else + return dmaalt_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..a653f15c241cdb413cfeee32310a5e49699ec021 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_dma.h @@ -0,0 +1,221 @@ +/* + * @brief DMA controller ROM API declarations and functions + * + * @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 __ROMAPI_DMA_H_ +#define __ROMAPI_DMA_H_ + +#include "hw_dmaaltd.h" + +/** @defgroup ROMAPI_DMA_WRAPPER CHIP: DMA controller ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** @brief Minimum byte alignment value needed for the channel table. + * Use 4 for 4 byte alginment, 8 for 8 byte alignment, etc. */ +#define MINDMATABLEALIGN 512 + +/** @brief Number of DMA channels the DMA controller supports. */ +#define NUMDMACHANNELS 22 + +/** + * @brief Get memory size in bytes needed for DMA controller driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_DMA_GetMemSize(void); + +/** + * @brief Initialize DMA controller + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to DMA controller init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_DMA_HANDLE_T ROM_DMA_Init(void *mem, ROM_DMA_INIT_T *pInit); + +/** + * @brief Configures a DMA channel + * @param pHandle : Pointer to driver context handle + * @param pCfg : Pointer to DMA channel configuration structure + * @param dmaCh : DMA channel to configure + * @return LPC_OK if no errors occured, or an error code + */ +ErrorCode_t ROM_DMA_SetupChannel(ROM_DMA_HANDLE_T pHandle, ROM_DMA_CHAN_CFG_T *pCfg, uint8_t dmaCh); + +/** + * @brief Initialzies a transfer descriptor queue for a channel + * @param pHandle : Pointer to driver context handle + * @param dmaCh : DMA channel to configure + * @param pQueue : Pointer to a queue to initialize + * @return LPC_OK if no errors occured, or an error code + */ +ErrorCode_t ROM_DMA_InitQueue(ROM_DMA_HANDLE_T pHandle, uint8_t dmaCh, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Registers an DMA controller callback for a queue + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_DMA_RegisterQueueCallback(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, uint32_t cbIndex, void *pCB); + +/** + * @brief Builds a transfer descriptor chain from the passed settings + * @param pHandle : Pointer to driver context handle + * @param pXferCfg : Pointer to the transfer configuration + * @param pDesc : Pointer to a descriptor to setup + * @param pDescPrev : Pointer to previous descriptor that will link to this one + * @return LPC_OK if no errors occured, or an error code + * @note When creating a DMA descriptor chain (more than 1 link), chain the descriptors + * together by passing the previous descriptor pointers for subsequenct calls to this function. + */ +ErrorCode_t ROM_DMA_BuildDescriptorChain(ROM_DMA_HANDLE_T pHandle, + ROM_DMA_XFERDESC_CFG_T *pXferCfg, + ROM_DMA_DESC_T *pDesc, + ROM_DMA_DESC_T *pDescPrev); + +/** + * @brief Returns the number of items transferred on the last descriptor chain (spent status only) + * @param pHandle : Pointer to driver context handle + * @param pDesc : Pointer to a descriptor chain to count + * @return LPC_OK if no errors occured, or an error code + */ +uint32_t ROM_DMA_GetTransferCount(ROM_DMA_HANDLE_T pHandle, ROM_DMA_DESC_T *pDesc); + +/** + * @brief Unstalls a descriptor chain that has been setup using the stallDesc option + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a descriptor chain to unstall + * @return Nothing + * @note If a descriptor in a chain is setup with the stallDesc!=0 option in the + * @ref ROM_DMA_XFERDESC_CFG_T setup structure, the descriptor will stall when it + * is loaded. A stalled descriptor is ready to be processed, but won't start until a + * call to this fucntion is made. + */ +void ROM_DMA_UnstallDescriptorChain(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Queues a transfer descriptor chain + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @param pDescChainHead : Pointer to the start of a descriptor chain to queue + * @return Nothing + */ +void ROM_DMA_QueueDescriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue, ROM_DMA_DESC_T *pDescChainHead); + +/** + * @brief Returns current status of next descriptor to be popped from the queue + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return Pointer to next pop descriptor, or ROM_DMA_DESC_STS_INVALID if no descriptors exist to be popped + * @note Only descriptors that are spent, aborted, or have an error can be popped. Calling ROM_DMA_StopQueue() + * will abort the current descriptor in progress. This function returns the next descriptor that can be popped + * regardless of status without actually popping it. + */ +ROM_DMA_DESC_STS_T ROM_DMA_GetQueuePopDescriptorStatus(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Pops (unqueues) an expired transfer descriptor from the queue - expired descriptors are in spent, error, or abort states + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return Pointer to popped descriptor, or NULL if no descriptors exist to be popped + * @note Only descriptors that are spent, aborted, or have an error can be popped. Calling ROM_DMA_StopQueue() + * will abort the current descriptor in progress. + */ +ROM_DMA_DESC_T *ROM_DMA_UnQueueDescriptor(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Starts or restarts a queue at the next descriptor chain + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return LPC_OK if the queue is started or currently started, or an error code + */ +ErrorCode_t ROM_DMA_StartQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Stops DMA and aborts current descriptor chain being processed in queue + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return LPC_OK if the queue is stopped or already stopped, or an error code + * @note If multiple descriptor chains are queued up, this aborts the current one + * being processed in queueing, ready, or busy states. All descriptors after the aborted + * descriptor remain ready. + */ +ErrorCode_t ROM_DMA_StopQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Stops DMA and completely flushes a transfer queue, queue is completely reset + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return Nothing + * @note Flushes the entire queue of all descriptors and stops DMA. + */ +void ROM_DMA_FlushQueue(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Returns the current queue state (ROM_DMA_QUEUE_STATES_T) + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return Current queue status (ROM_DMA_QUEUE_STATES_T) + */ +uint8_t ROM_DMA_GetQueueState(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief Forces a DMA transfer to trigger + * @param pHandle : Pointer to driver context handle + * @param pQueue : Pointer to a queue + * @return Nothing + */ +void ROM_DMA_ForceTrigger(ROM_DMA_HANDLE_T pHandle, ROM_DMA_QUEUE_T *pQueue); + +/** + * @brief DMA controller (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the DMA interrupt handler. + */ +void ROM_DMA_DMAHandler(ROM_DMA_HANDLE_T pHandle); + +/** + * @brief Return the DMA controller ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_DMA_GetDriverVersion(void); + +/** + * @} + */ + +#endif /* __ROMAPI_DMA_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.c new file mode 100644 index 0000000000000000000000000000000000000000..a68a27f74a04a97730ac3655f8eb8a74c1d78bb9 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.c @@ -0,0 +1,104 @@ +/* + * @brief I2C master ROM API declarations and functions + * These are the public ROM APIs and functions of the I2C master + * 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 "romapi_5410x.h" + +/* Get memory size in bytes needed for I2C master driver context */ +uint32_t ROM_I2CM_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CM_API->GetMemSize(); +#else + return i2cm_api.GetMemSize(); +#endif +} + +/* Initialize I2C master peripheral */ +ROM_I2CM_HANDLE_T ROM_I2CM_Init(void *mem, const ROM_I2CM_INIT_T *pInit) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CM_API->Init(mem, pInit); +#else + return i2cm_api.Init(mem, pInit); +#endif +} + +/* Set I2C master clock rate */ +uint32_t ROM_I2CM_SetClockRate(ROM_I2CM_HANDLE_T pHandle, uint32_t inRate, uint32_t i2cRate) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CM_API->SetClockRate(pHandle, inRate, i2cRate); +#else + return i2cm_api.SetClockRate(pHandle, inRate, i2cRate); +#endif +} + +/* Register a I2C master callback */ +void ROM_I2CM_RegisterCallback(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_CALLBACK_T cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CM_API->RegisterCallback(pHandle, cbIndex, pCB); +#else + i2cm_api.RegisterCallback(pHandle, cbIndex, pCB); +#endif +} + +/* Start a I2C master transfer */ +ErrorCode_t ROM_I2CM_Transfer(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_XFER_T *pXfer) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CM_API->Transfer(pHandle, pXfer); +#else + return i2cm_api.Transfer(pHandle, pXfer); +#endif +} + +/* I2C master transfer (interrupt) handler */ +void ROM_I2CM_TransferHandler(ROM_I2CM_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CM_API->TransferHandler(pHandle); +#else + i2cm_api.TransferHandler(pHandle); +#endif +} + +/* Return the I2C master ROM driver version */ +uint16_t ROM_I2CM_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CM_API->GetDriverVersion(); +#else + return i2cm_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.h new file mode 100644 index 0000000000000000000000000000000000000000..938ed00f215e1ba125621454f95adf12ceb50994 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cm.h @@ -0,0 +1,113 @@ +/* + * @brief I2C master ROM API declarations and functions + * + * @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 __ROMAPI_I2CM_H_ +#define __ROMAPI_I2CM_H_ + +#include "hw_i2cmd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_I2CM_WRAPPER CHIP: I2C master ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for I2C master driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_I2CM_GetMemSize(void); + +/** + * @brief Initialize I2C master peripheral + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to I2C master init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_I2CM_HANDLE_T ROM_I2CM_Init(void *mem, const ROM_I2CM_INIT_T *pInit); + +/** + * @brief Set I2C master clock rate + * @param pHandle : Pointer to driver context handle + * @param inRate : Base clock rate for the I2C peripheral in Hz + * @param i2cRate : Desired I2C master clock rate + * @return Actual I2C master clock rate + */ +uint32_t ROM_I2CM_SetClockRate(ROM_I2CM_HANDLE_T pHandle, uint32_t inRate, uint32_t i2cRate); + +/** + * @brief Register a I2C master callback + * @param pHandle : Pointer to driver context handle + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_I2CM_RegisterCallback(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_CALLBACK_T cbIndex, void *pCB); + +/** + * @brief Start a I2C master transfer + * @param pHandle : Pointer to driver context handle + * @param pXfer : Pointer to master transfer configuration + * @return Error code + * @note This function starts the transfer and returns immediately. + */ +ErrorCode_t ROM_I2CM_Transfer(ROM_I2CM_HANDLE_T pHandle, ROM_I2CM_XFER_T *pXfer); + +/** + * @brief I2C master transfer (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the I2C interrupt handler and + * is used in interrupt and DMA modes. + */ +void ROM_I2CM_TransferHandler(ROM_I2CM_HANDLE_T pHandle); + +/** + * @brief Return the I2C master ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_I2CM_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_I2CM_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.c new file mode 100644 index 0000000000000000000000000000000000000000..5b76583a5c61b3206fc4501d5565801f9f827865 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.c @@ -0,0 +1,92 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for I2C monitor driver context */ +uint32_t ROM_I2CMON_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CMON_API->GetMemSize(); +#else + return i2cmon_api.GetMemSize(); +#endif +} + +/* Initialize I2C monitor peripheral */ +ROM_I2CMON_HANDLE_T ROM_I2CMON_Init(void *mem, ROM_I2CMON_INIT_T *pInit) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CMON_API->Init(mem, pInit); +#else + return i2cmon_api.Init(mem, pInit); +#endif +} + +/* Register a I2C monitor callback */ +void ROM_I2CMON_RegisterCallback(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CALLBACK_T cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CMON_API->RegisterCallback(pHandle, cbIndex, pCB); +#else + i2cmon_api.RegisterCallback(pHandle, cbIndex, pCB); +#endif +} + +/* Start I2C monitoring */ +ErrorCode_t ROM_I2CMON_StartLog(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CAP_T *pCap) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CMON_API->StartLog(pHandle, pCap); +#else + return i2cmon_api.StartLog(pHandle, pCap); +#endif +} + +/* I2C monitor transfer (interrupt) handler */ +void ROM_I2CMON_TransferHandler(ROM_I2CMON_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CMON_API->TransferHandler(pHandle); +#else + i2cmon_api.TransferHandler(pHandle); +#endif +} + +/* Return the I2C monitor ROM driver version */ +uint16_t ROM_I2CMON_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CMON_API->GetDriverVersion(); +#else + return i2cmon_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.h new file mode 100644 index 0000000000000000000000000000000000000000..9dd3cafbfa2551b0d2285e61c9689a89e23830d7 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cmon.h @@ -0,0 +1,104 @@ +/* + * @brief I2C monitor ROM API declarations and functions + * + * @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 __ROMAPI_I2CMON_H_ +#define __ROMAPI_I2CMON_H_ + +#include "hw_i2cmond.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_I2CMON_WRAPPER CHIP: I2C monitor ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for I2C monitor driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_I2CMON_GetMemSize(void); + +/** + * @brief Initialize I2C monitor peripheral + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to I2C monitor init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_I2CMON_HANDLE_T ROM_I2CMON_Init(void *mem, ROM_I2CMON_INIT_T *pInit); + +/** + * @brief Register a I2C monitor callback + * @param pHandle : Pointer to driver context handle + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_I2CMON_RegisterCallback(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CALLBACK_T cbIndex, void *pCB); + +/** + * @brief Start I2C monitoring + * @param pHandle : Pointer to driver context handle + * @param pCap : Pointer to capture monitor configuration + * @return Error code + * @note This function starts the transfer and returns immediately. + */ +ErrorCode_t ROM_I2CMON_StartLog(ROM_I2CMON_HANDLE_T pHandle, ROM_I2CMON_CAP_T *pCap); + +/** + * @brief I2C monitor transfer (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the I2C interrupt handler and + * is used in interrupt and DMA modes. + */ +void ROM_I2CMON_TransferHandler(ROM_I2CMON_HANDLE_T pHandle); + +/** + * @brief Return the I2C monitor ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_I2CMON_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_I2CMON_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.c new file mode 100644 index 0000000000000000000000000000000000000000..edc0721b6cb283dd02dbb9afa300cc0336eec143 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.c @@ -0,0 +1,102 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for I2C slave driver context */ +uint32_t ROM_I2CS_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CS_API->GetMemSize(); +#else + return i2cs_api.GetMemSize(); +#endif +} + +/* Initialize I2C slave peripheral */ +ROM_I2CS_HANDLE_T ROM_I2CS_Init(void *mem, ROM_I2CS_INIT_T *pInit) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CS_API->Init(mem, pInit); +#else + return i2cs_api.Init(mem, pInit); +#endif +} + +/* Set I2C slave clock rate */ +void ROM_I2CS_SetupSlave(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_SLAVE_T *pSlaveSetup) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CS_API->SetupSlave(pHandle, pSlaveSetup); +#else + i2cs_api.SetupSlave(pHandle, pSlaveSetup); +#endif +} + +/* Register a I2C slave callback */ +void ROM_I2CS_RegisterCallback(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_CALLBACK_T cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CS_API->RegisterCallback(pHandle, cbIndex, pCB); +#else + i2cs_api.RegisterCallback(pHandle, cbIndex, pCB); +#endif +} + +/* Start a I2C slave transfer */ +ErrorCode_t ROM_I2CS_Transfer(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_XFER_T *pXfer) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CS_API->Transfer(pHandle, pXfer); +#else + return i2cs_api.Transfer(pHandle, pXfer); +#endif +} + +/* I2C slave transfer (interrupt) handler */ +void ROM_I2CS_TransferHandler(ROM_I2CS_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_I2CS_API->TransferHandler(pHandle); +#else + i2cs_api.TransferHandler(pHandle); +#endif +} + +/* Return the I2C slave ROM driver version */ +uint16_t ROM_I2CS_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_I2CS_API->GetDriverVersion(); +#else + return i2cs_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.h new file mode 100644 index 0000000000000000000000000000000000000000..416e7e581793da82b3763be651a8fb3f5d6505a3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_i2cs.h @@ -0,0 +1,113 @@ +/* + * @brief I2C slave ROM API declarations and functions + * + * @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 __ROMAPI_I2CS_H_ +#define __ROMAPI_I2CS_H_ + +#include "hw_i2csd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_I2CS_WRAPPER CHIP: I2C slave ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for I2C slave driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_I2CS_GetMemSize(void); + +/** + * @brief Initialize I2C slave peripheral + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to I2C slave init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_I2CS_HANDLE_T ROM_I2CS_Init(void *mem, ROM_I2CS_INIT_T *pInit); + +/** + * @brief Set I2C slave clock rate + * @param pHandle : Pointer to driver context handle + * @param pSlaveSetup : Slave setup data + * @return Nothing + * @note See the use model for more information on how to setup slave addresses. + */ +void ROM_I2CS_SetupSlave(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_SLAVE_T *pSlaveSetup); + +/** + * @brief Register a I2C slave callback + * @param pHandle : Pointer to driver context handle + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_I2CS_RegisterCallback(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_CALLBACK_T cbIndex, void *pCB); + +/** + * @brief Queues an I2C slave transfer + * @param pHandle : Pointer to driver context handle + * @param pXfer : Pointer to slave transfer configuration + * @return Always returns LPC_OK + * @note This functions never blocks. + */ +ErrorCode_t ROM_I2CS_Transfer(ROM_I2CS_HANDLE_T pHandle, ROM_I2CS_XFER_T *pXfer); + +/** + * @brief I2C slave transfer (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the I2C interrupt handler and + * is used in interrupt and DMA modes. + */ +void ROM_I2CS_TransferHandler(ROM_I2CS_HANDLE_T pHandle); + +/** + * @brief Return the I2C slave ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_I2CS_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_I2CS_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.c new file mode 100644 index 0000000000000000000000000000000000000000..83b6b12e97e1384908601338c9fea102a8ca7281 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.c @@ -0,0 +1,107 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for SPI master driver context */ +uint32_t ROM_SPIM_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIM_API->GetMemSize(); +#else + return spim_api.GetMemSize(); +#endif +} + +/* Initialize SPI master peripheral */ +ROM_SPIM_HANDLE_T ROM_SPIM_Init(void *mem, ROM_SPIM_INIT_T *pInit) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIM_API->Init(mem, pInit); +#else + return spim_api.Init(mem, pInit); +#endif +} + +void ROM_SPIM_RegisterCallback(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_CALLBACK_T cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_SPIM_API->RegisterCallback(pHandle, cbIndex, pCB); +#else + spim_api.RegisterCallback(pHandle, cbIndex, pCB); +#endif +} + +ErrorCode_t ROM_SPIM_SetupTransfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_CONFIG_T *pCfg) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIM_API->SetupTransfer(pHandle, pCfg); +#else + return spim_api.SetupTransfer(pHandle, pCfg); +#endif +} + +ErrorCode_t ROM_SPIM_Transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIM_API->Transfer(pHandle, pXfer); +#else + return spim_api.Transfer(pHandle, pXfer); +#endif +} + +void ROM_SPIM_TransferHandler(ROM_SPIM_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_SPIM_API->TransferHandler(pHandle); +#else + spim_api.TransferHandler(pHandle); +#endif +} + +void ROM_SPIM_ClosePendingTransfer(ROM_SPIM_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_SPIM_API->ClosePendingTransfer(pHandle); +#else + spim_api.ClosePendingTransfer(pHandle); +#endif +} + +/* Return the SPI master ROM driver version */ +uint16_t ROM_SPIM_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIM_API->GetDriverVersion(); +#else + return spim_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.h new file mode 100644 index 0000000000000000000000000000000000000000..faba2251bac3ca407de58156306928c939f40ca7 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spim.h @@ -0,0 +1,118 @@ +/* + * @brief SPI master ROM API declarations and functions + * + * @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 __ROMAPI_SPIM_H_ +#define __ROMAPI_SPIM_H_ + +#include "hw_spimd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_SPIM_WRAPPER CHIP: SPI master ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for SPI master driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_SPIM_GetMemSize(void); + +/** + * @brief Initialize SPI master peripheral + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to SPI master init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_SPIM_HANDLE_T ROM_SPIM_Init(void *mem, ROM_SPIM_INIT_T *pInit); + +/** + * @brief Register a SPI master callback + * @param pHandle : Pointer to driver context handle + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_SPIM_RegisterCallback(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_CALLBACK_T cbIndex, void *pCB); + +ErrorCode_t ROM_SPIM_SetupTransfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_CONFIG_T *pCfg); + +/** + * @brief Start a SPI master transfer + * @param pHandle : Pointer to driver context handle + * @param pXfer : Pointer to master transfer configuration + * @return Error code + * @note This function starts the transfer and returns immediately. + */ +ErrorCode_t ROM_SPIM_Transfer(ROM_SPIM_HANDLE_T pHandle, ROM_SPIM_XFER_T *pXfer); + +/** + * @brief SPI master transfer (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the SPI interrupt handler and + * is used in interrupt and DMA modes. + */ +void ROM_SPIM_TransferHandler(ROM_SPIM_HANDLE_T pHandle); + +/** + * @brief Safely stop a SPI master transfer + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function completes the SPI transfer at the next possible + * transfer completion state. This should be called when DMA is used and + * DMA transfer is complete, or whenever the transfer neesd to be aborted. + * It will safely transmit any data already inside the SPI transmit FIFOs + * before stopping. + */ +void ROM_SPIM_ClosePendingTransfer(ROM_SPIM_HANDLE_T pHandle); + +/** + * @brief Return the SPI master ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_SPIM_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_SPIM_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.c new file mode 100644 index 0000000000000000000000000000000000000000..934ce64e70da8f5b07dfb472717df14798cb2ab6 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.c @@ -0,0 +1,98 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for SPI slave driver context */ +uint32_t ROM_SPIS_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIS_API->GetMemSize(); +#else + return spis_api.GetMemSize(); +#endif +} + +/* Initialize SPI slave peripheral */ +ROM_SPIS_HANDLE_T ROM_SPIS_Init(void *mem, ROM_SPIS_INIT_T *pInit) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIS_API->Init(mem, pInit); +#else + return spis_api.Init(mem, pInit); +#endif +} + +void ROM_SPIS_RegisterCallback(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_CALLBACK_T cbIndex, void *pCB) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_SPIS_API->RegisterCallback(pHandle, cbIndex, pCB); +#else + spis_api.RegisterCallback(pHandle, cbIndex, pCB); +#endif +} + +ErrorCode_t ROM_SPIS_SetupSlave(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_SLAVE_T *pSlaveSetup) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIS_API->SetupSlave(pHandle, pSlaveSetup); +#else + return spis_api.SetupSlave(pHandle, pSlaveSetup); +#endif +} + +ErrorCode_t ROM_SPIS_Transfer(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIS_API->Transfer(pHandle, pXfer); +#else + return spis_api.Transfer(pHandle, pXfer); +#endif +} + +void ROM_SPIS_TransferHandler(ROM_SPIS_HANDLE_T pHandle) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_SPIS_API->TransferHandler(pHandle); +#else + spis_api.TransferHandler(pHandle); +#endif +} + +/* Return the SPI slave ROM driver version */ +uint16_t ROM_SPIS_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_SPIS_API->GetDriverVersion(); +#else + return spis_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.h new file mode 100644 index 0000000000000000000000000000000000000000..9418fab3acdb6aa823be99280e5eb845085a5f32 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_spis.h @@ -0,0 +1,113 @@ +/* + * @brief SPI slave ROM API declarations and functions + * + * @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 __ROMAPI_SPIS_H_ +#define __ROMAPI_SPIS_H_ + +#include "hw_spisd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_SPIS_WRAPPER CHIP: SPI slave ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for SPI slave driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_SPIS_GetMemSize(void); + +/** + * @brief Initialize SPI slave peripheral + * @param mem : Pointer to memory area used to driver context + * @param pInit : Pointer to SPI slave init data + * @return NULL on error, or a pointer to the device context handle + */ +ROM_SPIS_HANDLE_T ROM_SPIS_Init(void *mem, ROM_SPIS_INIT_T *pInit); + +/** + * @brief Register a SPI slave callback + * @param pHandle : Pointer to driver context handle + * @param cbIndex : Callback to register + * @param pCB : Pointer to callback function + * @return Nothing + */ +void ROM_SPIS_RegisterCallback(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_CALLBACK_T cbIndex, void *pCB); + +/** + * @brief Setup SPI slave transfer configuration + * @param pHandle : Pointer to driver context handle + * @param pSlaveSetup : Slave setup data + * @return Error code + * @note Sets up the slave interface configuration for a transfer. + */ +ErrorCode_t ROM_SPIS_SetupSlave(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_SLAVE_T *pSlaveSetup); + +/** + * @brief Start a SPI slave transfer + * @param pHandle : Pointer to driver context handle + * @param pXfer : Pointer to slave transfer configuration + * @return Error code + * @note This function starts the transfer and returns immediately. + */ +ErrorCode_t ROM_SPIS_Transfer(ROM_SPIS_HANDLE_T pHandle, ROM_SPIS_XFER_T *pXfer); + +/** + * @brief SPI slave transfer (interrupt) handler + * @param pHandle : Pointer to driver context handle + * @return Nothing + * @note This function should be called from the SPI interrupt handler and + * is used in interrupt and DMA modes. + */ +void ROM_SPIS_TransferHandler(ROM_SPIS_HANDLE_T pHandle); + +/** + * @brief Return the SPI slave ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_SPIS_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_SPIS_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..8c6e2ac331a7355a6650cfabf317e784647e5ec3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.c @@ -0,0 +1,154 @@ +/* + * @brief UART ROM API declarations and functions + * + * @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 "romapi_5410x.h" + +/* Get memory size in bytes needed for ADC driver context */ +uint32_t ROM_UART_GetMemSize(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->GetMemSize(); +#else + return uartrom_api.GetMemSize(); +#endif +} + +/* Initialize the UART ROM driver */ +UART_HANDLE_T ROM_UART_Init(void *pMem, uint32_t baseAddr, void *pUserData) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->Init(pMem, baseAddr, pUserData); +#else + return uartrom_api.Init(pMem, baseAddr, pUserData); +#endif +} + +/* Configure the UART peripheral */ +ErrorCode_t ROM_UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *pCfg) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->Configure(hUART, pCfg); +#else + return uartrom_api.Configure(hUART, pCfg); +#endif +} + +/* Calculate baudrate dividers and oversampling values */ +ErrorCode_t ROM_UART_CalBaud(UART_BAUD_T *baud) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->CalBaud(baud); +#else + return uartrom_api.CalBaud(baud); +#endif +} + +/* Set/Clear special control operations like BREAK, IDLE, etc., */ +void ROM_UART_SetCtrl(UART_HANDLE_T hUART, uint32_t cfgVal) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_UART_API->SetCtrl(hUART, cfgVal); +#else + uartrom_api.SetCtrl(hUART, cfgVal); +#endif +} + +/* Registers an UART callback function */ +ErrorCode_t ROM_UART_RegisterCB(UART_HANDLE_T hUART, UART_CBINDEX_T cbIndex, void (*pCbFunc)(UART_HANDLE_T, + UART_EVENT_T, + void *)) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->RegisterCB(hUART, cbIndex, pCbFunc); +#else + return uartrom_api.RegisterCB(hUART, cbIndex, pCbFunc); +#endif +} + +/* UART Event handler, should be called from the ISR */ +void ROM_UART_Handler(UART_HANDLE_T hUART) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_UART_API->Handler(hUART); +#else + uartrom_api.Handler(hUART); +#endif +} + +/* Send data to UART */ +ErrorCode_t ROM_UART_Send(UART_HANDLE_T hUART, const void *buffer, uint16_t size) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->Send(hUART, buffer, size); +#else + return uartrom_api.Send(hUART, buffer, size); +#endif +} + +/* Receive data from UART */ +ErrorCode_t ROM_UART_Receive(UART_HANDLE_T hUART, void *buffer, uint16_t size) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->Receive(hUART, buffer, size); +#else + return uartrom_api.Receive(hUART, buffer, size); +#endif +} + +/* Wait for UART TX to complete; Used for polling */ +void ROM_UART_WaitTx(UART_HANDLE_T hUART) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_UART_API->WaitTx(hUART); +#else + uartrom_api.WaitTx(hUART); +#endif +} + +/* Wait for UART data receive to complete; Used for polling */ +void ROM_UART_WaitRx(UART_HANDLE_T hUART) +{ +#if defined(ROMDRIVERSV2_PRESENT) + ROMAPI_UART_API->WaitRx(hUART); +#else + uartrom_api.WaitRx(hUART); +#endif +} + +/* Get Current verion of the UART ROM driver */ +uint16_t ROM_UART_GetDriverVersion(void) +{ +#if defined(ROMDRIVERSV2_PRESENT) + return ROMAPI_UART_API->GetDriverVersion(); +#else + return uartrom_api.GetDriverVersion(); +#endif +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..2a1da9c91bf66f6ecbb76950f39176fdc7b75901 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/romapi_uart.h @@ -0,0 +1,204 @@ +/* + * @brief UART ROM API declarations and functions + * + * @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 __ROMAPI_UART_H_ +#define __ROMAPI_UART_H_ + +#include "hw_uart_rom_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_UART_WRAPPER CHIP: UART ROM wrapper functions + * @ingroup ROMAPI_5410X + * @{ + */ + +/** + * @brief Get memory size in bytes needed for SPI master driver context + * @return Size in bytes needed for the ROM driver + */ +uint32_t ROM_UART_GetMemSize(void); + +/** + * @brief Initialize UART ROM Driver + * @param pMem : Pointer to memory area for driver context + * @param baseAddr : Base address of the UART peripheral + * @param pUserData : Pointer to User Data + * @return Pointer to the device context handle or NULL on alignment failure + * @note Parameter @a pMem must be a pointer to word aligned memory + * if the pointer is not word aligned (4-Byte) the function returns + * NULL. + */ +UART_HANDLE_T ROM_UART_Init(void *pMem, uint32_t baseAddr, void *pUserData); + +/** + * @brief Configure the UART peripheral + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param pCfg : Pointer to configuration structure #UART_CFG_T + * @return LPC_OK on Success, ERR_UART_PARAM if any of cfg values are invalid + */ +ErrorCode_t ROM_UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *pCfg); + +/** + * @brief Calculate UART Baud rate parameters + * @param baud : [IN/OUT] Pointer to baud rate structure + * @return LPC_OK on Success, ERR_UART_BAUDRATE baudrate for given frequency is not within limits + * @sa UART_BAUD_T + */ +ErrorCode_t ROM_UART_CalBaud(UART_BAUD_T *baud); + +/** + * @brief Set UART Control operations + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param cfgVal : Configuration value (one or more (OR'ed) values of #UART_BREAK_ON, #UART_TX_PAUSE etc) + * @return Nothing + * @note + * To set TX in BREAK state, use ROM_UART_SetCtrl(hUART, UART_BREAK_ON), to bring TX out of BREAK state + * use ROM_UART_SetCtrl(hUART, UART_BREAK_OFF). Us the above method will set TX line to BREAK state even + * if there is a data is being sent, hence the receiver might get a UART FRAME error and the data in progress might + * get lost. To avoid this application can pause TX before the TX gets to BREAK state by calling, + * ROM_UART_SetCtrl(hUART, #UART_BREAK_ON | #UART_TX_PAUSE) and release the break by calling + * ROM_UART_SetCtrl(hUART, #UART_BREAK_OFF | #UART_TX_RESUME).
+ * ROM_UART_SetCtrl(hUART, #UART_TX_PAUSE) will stop the TX until ROM_UART_SetCtrl(hUART, + * #UART_TX_RESUME) * this could be used to implement flow-control. + */ +void ROM_UART_SetCtrl(UART_HANDLE_T hUART, uint32_t cfgVal); + +/** + * @brief Registers a callback function associated with an event + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param cbIndex : Index of the call-back function (Associated with an event) + * @param pCbFunc : Pointer to callback function + * @return Success or failure + * @retval LPC_OK Callback successfully registered + * @retval ERR_UART_PARAM Invaild event parameter for @a cbIndex + */ +ErrorCode_t ROM_UART_RegisterCB(UART_HANDLE_T hUART, UART_CBINDEX_T cbIndex, void (*pCbFunc)(UART_HANDLE_T, + UART_EVENT_T, + void *)); + +/** + * @brief UART Event handler function (Usually called from interrupt handler) + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @return Nothing + */ +void ROM_UART_Handler(UART_HANDLE_T hUART); + +/** + * @brief Send data to UART + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param buffer : Buffer to send + * @param size : Number of items in buffer + * @return LPC_OK when buffer is queued successfully for sending + * @note If the UART Data size is 9, then buffer should be of type + * uint16_t *, size should be number of uint16_t (not size in bytes). + */ +ErrorCode_t ROM_UART_Send(UART_HANDLE_T hUART, const void *buffer, uint16_t size); + +/** + * @brief Receive data from UART + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param buffer : Buffer to send + * @param size : Number of items in buffer + * @return LPC_OK when buffer is queued successfully for receiving data + * @note If the UART Data size is 9, then buffer should be of type + * uint16_t *, size should be number of uint16_t (not size in bytes). + */ +ErrorCode_t ROM_UART_Receive(UART_HANDLE_T hUART, void *buffer, uint16_t size); + +/** + * @brief Send data to UART [Blocking] + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param buffer : Buffer to send + * @param size : Number of items in buffer + * @return LPC_OK when buffer is queued successfully for sending + * @note If the UART Data size is 9, then buffer should be of type + * uint16_t *, size should be number of uint16_t (not size in bytes). + * This API is not in the ROM this is a wrapper API, that uses + * @a ROM_UART_Send() and @a ROM_UART_FlushTx() + */ +ErrorCode_t ROM_UART_SendBlock(UART_HANDLE_T hUART, const void *buffer, uint16_t size); + +/** + * @brief Receive data from UART [Blocking] + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @param buffer : Buffer to send + * @param size : Number of items in buffer + * @return LPC_OK when buffer is queued successfully for receiving data + * @note If the UART Data size is 9, then buffer should be of type + * uint16_t *, size should be number of uint16_t (not size in bytes). + * This API is not in the ROM this is a wrapper API, that uses + * @a ROM_UART_Receive() and @a ROM_UART_FetchRx() + */ +ErrorCode_t ROM_UART_ReceiveBlock(UART_HANDLE_T hUART, void *buffer, uint16_t size); + +/** + * @brief Wait for the current TX buffer to be sent + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @return Nothing + * @note This call will bock the excution till all the data bytes are sent. + * @sa ROM_UART_Send() + */ +void ROM_UART_WaitTx(UART_HANDLE_T hUART); + +/** + * @brief Complete the current Receive transfer + * @param hUART : Handle to UART obtained using ROM_UART_Init() + * @return Nothing + * @note This call will bock the excution till all the data bytes are read, + * if there is no RX in progress this call will read and discard the current + * pending RX data and the incoming data until there is no data coming from uart + * atleast for one data time, mainly used for discarding UART frames that had + * started arriving and overflown before the ROM_UART_Receive was called. + * @sa ROM_UART_Receive() + */ +void ROM_UART_WaitRx(UART_HANDLE_T hUART); + +/** + * @brief Return the UART ROM driver version + * @return Driver version number + * @note The returned driver version number consists of a major and minor + * number, with the minor number in the lower 8 bits and the major number in + * the upper 8 bits. + */ +uint16_t ROM_UART_GetDriverVersion(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_UART_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..4426dfb231f57e014f3c6dfa244503bed192a25a --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.c @@ -0,0 +1,48 @@ +/* + * @brief LPC5410X RTC chip 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..3c6743e4d555fe5250563d4abd14e9cee4e57c50 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/rtc_5410x.h @@ -0,0 +1,310 @@ +/* + * @brief LPC5410X RTC chip 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 __RTC_5410X_H_ +#define __RTC_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup RTC_5410X CHIP: LPC5410X Real Time clock + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X Real Time clock register block structure + */ +typedef struct { /*!< RTC */ + __IO uint32_t CTRL; /*!< RTC control register */ + __IO uint32_t MATCH; /*!< PRTC match (alarm) register */ + __IO uint32_t COUNT; /*!< RTC counter register */ + __IO uint32_t WAKE; /*!< RTC high-resolution/wake-up timer control register */ +} LPC_RTC_T; + +/* CTRL register defniitions */ +#define RTC_CTRL_SWRESET (1 << 0) /*!< Apply reset to RTC */ +#define RTC_CTRL_OFD (1 << 1) /*!< Oscillator fail detect status (failed bit) */ +#define RTC_CTRL_ALARM1HZ (1 << 2) /*!< RTC 1 Hz timer alarm flag status (match) bit */ +#define RTC_CTRL_WAKE1KHZ (1 << 3) /*!< RTC 1 kHz timer wake-up flag status (timeout) bit */ +#define RTC_CTRL_ALARMDPD_EN (1 << 4) /*!< RTC 1 Hz timer alarm for Deep power-down enable bit */ +#define RTC_CTRL_WAKEDPD_EN (1 << 5) /*!< RTC 1 kHz timer wake-up for Deep power-down enable bit */ +#define RTC_CTRL_RTC1KHZ_EN (1 << 6) /*!< RTC 1 kHz clock enable bit */ +#define RTC_CTRL_RTC_EN (1 << 7) /*!< RTC enable bit */ +#define RTC_CTRL_MASK ((uint32_t) 0xF1) /*!< RTC Control register Mask for reserved and status bits */ + +/** + * @brief Initialize the RTC peripheral + * @param pRTC : RTC peripheral selected + * @return None + */ +STATIC INLINE void Chip_RTC_Init(LPC_RTC_T *pRTC) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_RTC); + Chip_SYSCON_PeriphReset(RESET_RTC); +} + +/** + * @brief De-initialize the RTC peripheral + * @param pRTC : RTC peripheral selected + * @return None + */ +STATIC INLINE void Chip_RTC_DeInit(LPC_RTC_T *pRTC) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_RTC); +} + +/** + * @brief Enable RTC options + * @param pRTC : The base address of RTC block + * @param flags : And OR'ed value of RTC_CTRL_* definitions to enable + * @return Nothing + * @note You can enable multiple RTC options at once using this function + * by OR'ing them together. It is recommended to only use the + * RTC_CTRL_ALARMDPD_EN, RTC_CTRL_WAKEDPD_EN, RTC_CTRL_RTC1KHZ_EN, and + * RTC_CTRL_RTC_EN flags with this function. + */ +STATIC INLINE void Chip_RTC_EnableOptions(LPC_RTC_T *pRTC, uint32_t flags) +{ + pRTC->CTRL = (pRTC->CTRL & RTC_CTRL_MASK) | flags; +} + +/** + * @brief Disable RTC options + * @param pRTC : The base address of RTC block + * @param flags : And OR'ed value of RTC_CTRL_* definitions to disable + * @return Nothing + * @note You can enable multiple RTC options at once using this function + * by OR'ing them together. It is recommended to only use the + * RTC_CTRL_ALARMDPD_EN, RTC_CTRL_WAKEDPD_EN, RTC_CTRL_RTC1KHZ_EN, and + * RTC_CTRL_RTC_EN flags with this function. + */ +STATIC INLINE void Chip_RTC_DisableOptions(LPC_RTC_T *pRTC, uint32_t flags) +{ + pRTC->CTRL = (pRTC->CTRL & RTC_CTRL_MASK) & ~flags; +} + +/** + * @brief Reset RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note The RTC state will be returned to it's default. + */ +STATIC INLINE void Chip_RTC_Reset(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_SWRESET); + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_SWRESET); +} + +/** + * @brief Enables the RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_EnableOptions() with the + * RTC_CTRL_RTC_EN flag to enable the RTC. + */ +STATIC INLINE void Chip_RTC_Enable(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_RTC_EN); +} + +/** + * @brief Disables the RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_DisableOptions() with the + * RTC_CTRL_RTC_EN flag to enable the RTC. + */ +STATIC INLINE void Chip_RTC_Disable(LPC_RTC_T *pRTC) +{ + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_RTC_EN); +} + +/** + * @brief Enables the RTC 1KHz high resolution timer + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_EnableOptions() with the + * RTC_CTRL_RTC1KHZ_EN flag to enable the high resolution + * timer. + */ +STATIC INLINE void Chip_RTC_Enable1KHZ(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_RTC1KHZ_EN); +} + +/** + * @brief Disables the RTC 1KHz high resolution timer + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_DisableOptions() with the + * RTC_CTRL_RTC1KHZ_EN flag to disable the high resolution + * timer. + */ +STATIC INLINE void Chip_RTC_Disable1KHZ(LPC_RTC_T *pRTC) +{ + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_RTC1KHZ_EN); +} + +/** + * @brief Enables selected RTC wakeup events + * @param pRTC : The base address of RTC block + * @param ints : Wakeup events to enable + * @return Nothing + * @note Select either one or both (OR'ed) RTC_CTRL_ALARMDPD_EN + * and RTC_CTRL_WAKEDPD_EN values to enabled. You can also + * use Chip_RTC_EnableOptions() with the flags to enable + * the events. + */ +STATIC INLINE void Chip_RTC_EnableWakeup(LPC_RTC_T *pRTC, uint32_t ints) +{ + Chip_RTC_EnableOptions(pRTC, ints); +} + +/** + * @brief Disables selected RTC wakeup events + * @param pRTC : The base address of RTC block + * @param ints : Wakeup events to disable + * @return Nothing + * @note Select either one or both (OR'ed) RTC_CTRL_ALARMDPD_EN + * and RTC_CTRL_WAKEDPD_EN values to disabled. You can also + * use Chip_RTC_DisableOptions() with the flags to disable + * the events. + */ +STATIC INLINE void Chip_RTC_DisableWakeup(LPC_RTC_T *pRTC, uint32_t ints) +{ + Chip_RTC_DisableOptions(pRTC, ints); +} + +/** + * @brief Clears latched RTC statuses + * @param pRTC : The base address of RTC block + * @param stsMask : OR'ed status bits to clear + * @return Nothing + * @note Use and OR'ed stsMask value of RTC_CTRL_OFD, RTC_CTRL_ALARM1HZ, + * and RTC_CTRL_WAKE1KHZ to clear specific RTC states. + */ +STATIC INLINE void Chip_RTC_ClearStatus(LPC_RTC_T *pRTC, uint32_t stsMask) +{ + pRTC->CTRL = (pRTC->CTRL & RTC_CTRL_MASK) | stsMask; +} + +/** + * @brief Return RTC control/status register + * @param pRTC : The base address of RTC block + * @return The current RTC control/status register + * @note Mask the return value with a RTC_CTRL_* definitions to determine + * which bits are set. For example, mask the return value with + * RTC_CTRL_ALARM1HZ to determine if the alarm interrupt is pending. + */ +STATIC INLINE uint32_t Chip_RTC_GetStatus(LPC_RTC_T *pRTC) +{ + return pRTC->CTRL; +} + +/** + * @brief Set RTC match value for alarm status/interrupt + * @param pRTC : The base address of RTC block + * @param count : Alarm event time + * @return Nothing + */ +STATIC INLINE void Chip_RTC_SetAlarm(LPC_RTC_T *pRTC, uint32_t count) +{ + pRTC->MATCH = count; +} + +/** + * @brief Return the RTC match value used for alarm status/interrupt + * @param pRTC : The base address of RTC block + * @return Alarm event time + */ +STATIC INLINE uint32_t Chip_RTC_GetAlarm(LPC_RTC_T *pRTC) +{ + return pRTC->MATCH; +} + +/** + * @brief Set RTC match count for 1 second timer count + * @param pRTC : The base address of RTC block + * @param count : Initial count to set + * @return Nothing + * @note Only write to this register when the RTC_CTRL_RTC_EN bit in + * the CTRL Register is 0. The counter increments one second + * after the RTC_CTRL_RTC_EN bit is set. + */ +STATIC INLINE void Chip_RTC_SetCount(LPC_RTC_T *pRTC, uint32_t count) +{ + pRTC->COUNT = count; +} + +/** + * @brief Get current RTC 1 second timer count + * @param pRTC : The base address of RTC block + * @return current RTC 1 second timer count + */ +STATIC INLINE uint32_t Chip_RTC_GetCount(LPC_RTC_T *pRTC) +{ + return pRTC->COUNT; +} + +/** + * @brief Set RTC wake count countdown value (in mS ticks) + * @param pRTC : The base address of RTC block + * @param count : wakeup time in milliSeconds + * @return Nothing + * @note A write pre-loads a start count value into the wake-up + * timer and initializes a count-down sequence. + */ +STATIC INLINE void Chip_RTC_SetWake(LPC_RTC_T *pRTC, uint16_t count) +{ + pRTC->WAKE = count; +} + +/** + * @brief Get RTC wake count countdown value + * @param pRTC : The base address of RTC block + * @return current RTC wake count countdown value (in mS) + */ +STATIC INLINE uint16_t Chip_RTC_GetWake(LPC_RTC_T *pRTC) +{ + return pRTC->WAKE; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RTC_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..aac69a27afe5b4c73dd884a3ffcdd332cf129f23 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.c @@ -0,0 +1,81 @@ +/* + * @brief LPC5410X State Configurable Timer 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize SCT */ +void Chip_SCT_Init(LPC_SCT_T *pSCT) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_SCT0); + Chip_SYSCON_PeriphReset(RESET_SCT0); +} + +/* Shutdown SCT */ +void Chip_SCT_DeInit(LPC_SCT_T *pSCT) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_SCT0); +} + +/* 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))); + pSCT->RES = tem | (value << (2 * outnum)); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..1992df899e5540a2bb0e03532b0c59ec3ac13432 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_5410x.h @@ -0,0 +1,504 @@ +/* + * @brief LPC5410X State Configurable Timer (SCT) Chip 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 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_5410X_H_ +#define __SCT_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SCT_5410X CHIP: LPC5410X State Configurable Timer driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/* match/cap registers, events, states, inputs, outputs + * + * @brief SCT Module configuration + */ +#define CONFIG_SCT_nEV (13) /*!< Number of events */ +#define CONFIG_SCT_nRG (13) /*!< Number of match/compare registers */ +#define CONFIG_SCT_nOU (8) /*!< Number of outputs */ +#define CONFIG_SCT_nIN (8) /*!< Number of outputs */ + +/** + * @brief State Configurable Timer register block structure + */ +typedef struct { + __IO uint32_t CONFIG; /*!< Configuration Register */ + + 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 */ + }; + + }; + + __IO uint16_t LIMIT_L; /*!< limit register for counter L */ + __IO uint16_t LIMIT_H; /*!< limit register for counter H */ + __IO uint16_t HALT_L; /*!< halt register for counter L */ + __IO uint16_t HALT_H; /*!< halt register for counter H */ + __IO uint16_t STOP_L; /*!< stop register for counter L */ + __IO uint16_t STOP_H; /*!< stop register for counter H */ + __IO uint16_t START_L; /*!< start register for counter L */ + __IO uint16_t START_H; /*!< start register for counter H */ + uint32_t RESERVED1[10]; /*!< 0x03C reserved */ + + union { + __IO uint32_t COUNT_U; /*!< counter register */ + + struct { + __IO uint16_t COUNT_L; /*!< counter register for counter L */ + __IO uint16_t COUNT_H; /*!< counter register for counter H */ + }; + + }; + + __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 */ + __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 DMA0REQUEST; /*!< DMA0 Request Register */ + __IO uint32_t DMA1REQUEST; /*!< DMA1 Request Register */ + uint32_t RESERVED2[35]; + __IO uint32_t EVEN; /*!< event enable register */ + __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; /*!< SCTMATCH[i].U Unified 32-bit register */ + + struct { + uint16_t L; /*!< SCTMATCH[i].L Access to L value */ + uint16_t H; /*!< SCTMATCH[i].H Access to H value */ + }; + + } MATCH[CONFIG_SCT_nRG]; + + __I union { + uint32_t U; /*!< SCTCAP[i].U Unified 32-bit register */ + + struct { + uint16_t L; /*!< SCTCAP[i].L Access to L value */ + uint16_t H; /*!< SCTCAP[i].H Access to H value */ + }; + + } CAP[CONFIG_SCT_nRG]; + + }; + + uint32_t RESERVED3[48 + (16 - CONFIG_SCT_nRG)]; + + union { + + __IO union { /* 0x200-... Match Reload / Capture Control value */ + uint32_t U; /* SCTMATCHREL[i].U Unified 32-bit register */ + + struct { + uint16_t L; /* SCTMATCHREL[i].L Access to L value */ + uint16_t H; /* SCTMATCHREL[i].H Access to H value */ + }; + + } MATCHREL[CONFIG_SCT_nRG]; + + __IO union { + uint32_t U; /* SCTCAPCTRL[i].U Unified 32-bit register */ + + struct { + uint16_t L; /* SCTCAPCTRL[i].L Access to H value */ + uint16_t H; /* SCTCAPCTRL[i].H Access to H value */ + }; + + } CAPCTRL[CONFIG_SCT_nRG]; + + }; + + uint32_t RESERVED6[48 + (16 - CONFIG_SCT_nRG)]; + + __IO struct { /* 0x300-0x3FC SCTEVENT[i].STATE / SCTEVENT[i].CTRL*/ + uint32_t STATE; /* Event State Register */ + uint32_t CTRL; /* Event Control Register */ + } EVENT[CONFIG_SCT_nEV]; + + uint32_t RESERVED9[128 - 2 * CONFIG_SCT_nEV]; /*!< ...-0x4FC reserved */ + + __IO struct { /*!< 0x500-0x57C SCTOUT[i].SET / SCTOUT[i].CLR */ + uint32_t SET; /*!< Output n Set Register */ + uint32_t CLR; /*!< Output n Clear Register */ + } OUT[CONFIG_SCT_nOU]; + + uint32_t RESERVED10[191 - 2 * CONFIG_SCT_nOU]; /*!< ...-0x7F8 reserved */ + __I uint32_t MODULECONTENT; /*!< 0x7FC Module Content */ +} LPC_SCT_T; + +/** + * @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_CLKMODE_SYSCLK (0x0 << 1) /*!< System clock */ +#define SCT_CONFIG_CLKMODE_PRESCALED_SYSCLK (0x1 << 1) /*!< Prescaled system clock */ +#define SCT_CONFIG_CLKMODE_SCT_INPUT (0x2 << 1) /*!< Input clock/edge selected in CKSEL field */ +#define SCT_CONFIG_CLKMODE_PRESCALED_SCT_INPUT (0x3 << 1) /*!< Prescaled input clock/edge selected in CKSEL field */ + +#define SCT_CONFIG_CKSEL_RISING_IN_0 (0x0UL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_0 (0x1UL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_1 (0x2UL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_1 (0x3UL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_2 (0x4UL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_2 (0x5UL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_3 (0x6UL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_3 (0x7UL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_4 (0x8UL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_4 (0x9UL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_5 (0xAUL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_5 (0xBUL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_6 (0xCUL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_6 (0xDUL << 3) +#define SCT_CONFIG_CKSEL_RISING_IN_7 (0xEUL << 3) +#define SCT_CONFIG_CKSEL_FALLING_IN_7 (0xFUL << 3) +#define SCT_CONFIG_NORELOADL_U (0x1 << 7) /*!< Operate as 1 32-bit counter */ +#define SCT_CONFIG_NORELOADH (0x1 << 8) /*!< Operate as 1 32-bit counter */ +#define SCT_CONFIG_AUTOLIMIT_U (0x1UL << 17) +#define SCT_CONFIG_AUTOLIMIT_L (0x1UL << 17) +#define SCT_CONFIG_AUTOLIMIT_H (0x1UL << 18) + +/** + * @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 */ + +#define SCT_EV_CTRL_MATCHSEL(reg) (reg << 0) +#define SCT_EV_CTRL_HEVENT_L (0UL << 4) +#define SCT_EV_CTRL_HEVENT_H (1UL << 4) +#define SCT_EV_CTRL_OUTSEL_INPUT (0UL << 5) +#define SCT_EV_CTRL_OUTSEL_OUTPUT (0UL << 5) +#define SCT_EV_CTRL_IOSEL(signal) (signal << 6) + +#define SCT_EV_CTRL_IOCOND_LOW (0UL << 10) +#define SCT_EV_CTRL_IOCOND_RISE (0x1UL << 10) +#define SCT_EV_CTRL_IOCOND_FALL (0x2UL << 10) +#define SCT_EV_CTRL_IOCOND_HIGH (0x3UL << 10) +#define SCT_EV_CTRL_COMBMODE_OR (0x0UL << 12) +#define SCT_EV_CTRL_COMBMODE_MATCH (0x1UL << 12) +#define SCT_EV_CTRL_COMBMODE_IO (0x2UL << 12) +#define SCT_EV_CTRL_COMBMODE_AND (0x3UL << 12) +#define SCT_EV_CTRL_STATELD (0x1UL << 14) +#define SCT_EV_CTRL_STATEV(x) (x << 15) +#define SCT_EV_CTRL_MATCHMEM (0x1UL << 20) +#define SCT_EV_CTRL_DIRECTION_INDEPENDENT (0x0UL << 21) +#define SCT_EV_CTRL_DIRECTION_UP (0x1UL << 21) +#define SCT_EV_CTRL_DIRECTION_DOWN (0x2UL << 21) + +/** + * @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, + SCT_MATCH_2, + SCT_MATCH_3, + SCT_MATCH_4, + SCT_MATCH_5, + SCT_MATCH_6, + SCT_MATCH_7, + SCT_MATCH_8, + SCT_MATCH_9, + SCT_MATCH_10, + SCT_MATCH_11, + SCT_MATCH_12, + SCT_MATCH_13, + SCT_MATCH_14, + SCT_MATCH_15 +} 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 */ + SCT_EVT_5 = (1 << 5), /*!< Event 5 */ + SCT_EVT_6 = (1 << 6), /*!< Event 6 */ + SCT_EVT_7 = (1 << 7), /*!< Event 7 */ + SCT_EVT_8 = (1 << 8), /*!< Event 8 */ + SCT_EVT_9 = (1 << 9), /*!< Event 9 */ + SCT_EVT_10 = (1 << 10), /*!< Event 10 */ + SCT_EVT_11 = (1 << 11), /*!< Event 11 */ + SCT_EVT_12 = (1 << 12), /*!< Event 12 */ + SCT_EVT_13 = (1 << 13), /*!< Event 13 */ + SCT_EVT_14 = (1 << 14), /*!< Event 14 */ + SCT_EVT_15 = (1 << 15) /*!< Event 15 */ +} CHIP_SCT_EVENT_T; + +/** + * @brief Set event control register + * @param pSCT : The base of SCT peripheral on the chip + * @param event_number + * @param value : The 32-bit event control setting + * @return Nothing + */ +STATIC INLINE void Chip_SCT_EventControl(LPC_SCT_T *pSCT, uint32_t event_number, + uint32_t value) { + pSCT->EVENT[event_number].CTRL = value; +} + +/** + * @brief Set event state mask register + * @param pSCT : The base of SCT peripheral on the chip + * @param event_number + * @param event_state_mask : The 32-bit event state mask setting + * @return Nothing + */ +STATIC INLINE void Chip_SCT_EventStateMask(LPC_SCT_T *pSCT, uint32_t event_number, + uint32_t event_state_mask) { + pSCT->EVENT[event_number].STATE = event_state_mask; +} + +/** + * @brief Set configuration register + * @param pSCT : The base of SCT peripheral on the chip + * @param cfg : The 32-bit configuration setting + * @return Nothing + */ +STATIC INLINE void Chip_SCT_Config(LPC_SCT_T *pSCT, uint32_t cfg) { + pSCT->CONFIG = cfg; +} + +/** + * @brief Configures the Limit register + * @param pSCT : The base of SCT peripheral on the chip + * @param value : The 32-bit Limit register value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_Limit(LPC_SCT_T *pSCT, uint32_t value) { + pSCT->LIMIT_L = 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; +} + +/** + * @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); +} + +/** + * @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; +} + +/** + * @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; +} + +/** + * @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); +} + +/** + * @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_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..aca456505453447bc6fabba97e30026cfbffaceb --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.c @@ -0,0 +1,86 @@ +/* + * @brief LPC5410x State Configurable Timer PWM 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 + ****************************************************************************/ + +/***************************************************************************** + * 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->EVENT[ix].CTRL = index | (1 << 12); + pSCT->EVENT[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))); +} + +/* 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_L = 0; + pSCT->REGMODE_H = 0; + Chip_SCT_SetMatchCount(pSCT, SCT_MATCH_0, 0); + Chip_SCT_SetMatchReload(pSCT, SCT_MATCH_0, rate); + pSCT->EVENT[0].CTRL = 1 << 12; + pSCT->EVENT[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); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..b1b8c93663d48c83dc8267b12ffb4aa230cce9d6 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sct_pwm_5410x.h @@ -0,0 +1,178 @@ +/* + * @brief LPC5410x State Configurable Timer (SCT/PWM) Chip 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 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_5410X_H_ +#define __SCT_PWM_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SCT_PWM_5410X CHIP: LPC5410X State Configurable Timer PWM driver + * + * For more information on how to use the driver please visit the FAQ page at + * + * www.lpcware.com + * + * @ingroup CHIP_5410X_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_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/stopwatch_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/stopwatch_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..483df42692021f5639fe0ef3b06e9a7b6e424f82 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/stopwatch_5410x.c @@ -0,0 +1,109 @@ +/* + * @brief LPC5410x specific stopwatch implementation + * + * @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 "stopwatch.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* Precompute these to optimize runtime */ +static uint32_t ticksPerSecond; +static uint32_t ticksPerMs; +static uint32_t ticksPerUs; + +/* Use this timer for stopwatch */ +#define LPC_TIMER32_1 LPC_TIMER0 + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize stopwatch */ +void StopWatch_Init(void) +{ + /* Set prescaler to divide by 8 */ + const uint32_t prescaleDivisor = 8; + Chip_TIMER_Init(LPC_TIMER32_1); + Chip_TIMER_PrescaleSet(LPC_TIMER32_1, prescaleDivisor - 1); + Chip_TIMER_Enable(LPC_TIMER32_1); + + /* Pre-compute tick rate. */ + ticksPerSecond = Chip_Clock_GetAsyncSyscon_ClockRate() / prescaleDivisor; + ticksPerMs = ticksPerSecond / 1000; + ticksPerUs = ticksPerSecond / 1000000; +} + +/* Start a stopwatch */ +uint32_t StopWatch_Start(void) +{ + /* Return the current timer count. */ + return Chip_TIMER_ReadCount(LPC_TIMER32_1); +} + +/* 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; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..860a8ae36f28d7a2718ee230b49387e08d38af1b --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.c @@ -0,0 +1,167 @@ +/* + * @brief LPC5410X System & Control 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 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 non-maskable interrupt (NMI) */ +void Chip_SYSCON_SetNMISource(uint32_t intsrc) +{ + uint32_t reg; + + reg = LPC_SYSCON->NMISRC; +#if defined(CORE_M4) + reg &= ~SYSCON_NMISRC_M4_ENABLE; +#else + reg &= ~SYSCON_NMISRC_M0_ENABLE; + intsrc = (intsrc << 8); +#endif + + /* First write without NMI bit, and then write source */ + LPC_SYSCON->NMISRC = reg; + LPC_SYSCON->NMISRC = reg | intsrc; +} + +/* Enable interrupt used for NMI source */ +void Chip_SYSCON_EnableNMISource(void) +{ +#if defined(CORE_M4) + LPC_SYSCON->NMISRC |= SYSCON_NMISRC_M4_ENABLE; +#else + LPC_SYSCON->NMISRC |= SYSCON_NMISRC_M0_ENABLE; +#endif +} + +/* Disable interrupt used for NMI source */ +void Chip_SYSCON_DisableNMISource(void) +{ +#if defined(CORE_M4) + LPC_SYSCON->NMISRC &= ~SYSCON_NMISRC_M4_ENABLE; +#else + LPC_SYSCON->NMISRC &= ~SYSCON_NMISRC_M0_ENABLE; +#endif +} + +/* Enable or disable asynchronous APB bridge and subsystem */ +void Chip_SYSCON_Enable_ASYNC_Syscon(bool enable) +{ + if (enable) { + LPC_SYSCON->ASYNCAPBCTRL = 0x01; + } + else { + LPC_SYSCON->ASYNCAPBCTRL = 0x00; + } +} + +/* Resets a peripheral */ +void Chip_SYSCON_PeriphReset(CHIP_SYSCON_PERIPH_RESET_T periph) +{ + uint32_t pid = (uint32_t) periph; + + if (pid >= 128) { + /* Async resets mapped to 128 and above, offset for peripheral bit index */ + pid = 1 << (((uint32_t) periph) - 128); + LPC_ASYNC_SYSCON->ASYNCPRESETCTRLSET = pid; + LPC_ASYNC_SYSCON->ASYNCPRESETCTRLCLR = pid; + } + else if (periph >= 32) { + pid = 1 << (((uint32_t) periph) - 32); + LPC_SYSCON->PRESETCTRLSET[1] = pid; + LPC_SYSCON->PRESETCTRLCLR[1] = pid; + } + else { + pid = 1 << ((uint32_t) periph); + LPC_SYSCON->PRESETCTRLSET[0] = pid; + LPC_SYSCON->PRESETCTRLCLR[0] = pid; + } +} + +/* Returns the computed value for a frequency measurement cycle */ +uint32_t Chip_SYSCON_GetCompFreqMeas(uint32_t refClockRate) +{ + uint32_t capval; + uint64_t clkrate = 0; + + /* Get raw capture value */ + capval = Chip_SYSCON_GetRawFreqMeasCapval(); + + /* Limit CAPVAL check */ + if (capval > 2) { + clkrate = (((uint64_t) capval - 2) * (uint64_t) refClockRate) / 0x4000; + } + + return (uint32_t) clkrate; +} + +void Chip_SYSCON_PowerUp(uint32_t powerupmask) +{ + /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */ + if (powerupmask & SYSCON_PDRUNCFG_PD_SYS_PLL) { + volatile uint32_t delayX; + uint32_t maxCCO = (1 << 18) | 0x3fff; + uint32_t curSSCTRL = LPC_SYSCON->SYSPLLSSCTRL[0]; + + /* If NOT using spread spectrum mode */ + if (curSSCTRL & (1 << 18)) { + + /* Turn on PLL */ + LPC_SYSCON->PDRUNCFGCLR = SYSCON_PDRUNCFG_PD_SYS_PLL; + + /* this sequence acclerates the PLL lock time */ + LPC_SYSCON->SYSPLLSSCTRL[0] = maxCCO | (1 << 17); /* Set mreq to activate */ + LPC_SYSCON->SYSPLLSSCTRL[0] = maxCCO; /* clear mreq to prepare for restoring mreq */ + + /* Delay for 20 uSec @ 12Mhz*/ + for (delayX = 0; delayX < 48; ++delayX) {} + + /* set original value back with mreq */ + LPC_SYSCON->SYSPLLSSCTRL[0] = curSSCTRL | (1 << 17); + } + } + + /* Enable peripheral states by setting low */ + LPC_SYSCON->PDRUNCFGCLR = powerupmask; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..3901eb5657f3801fe6320ec77a9ad2845e408571 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/syscon_5410x.h @@ -0,0 +1,567 @@ +/* + * @brief LPC5410X System & Control driver inclusion file + * + * @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 __SYSCON_5410X_H_ +#define __SYSCON_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SYSCON_5410X CHIP: LPC5410X System and Control Driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief LPC5410X Main system configuration register block structure + */ +typedef struct { + __IO uint32_t SYSMEMREMAP; /*!< System Remap register */ + __I uint32_t RESERVED0[4]; + __IO uint32_t SYSTCKCAL; /*!< System Tick Calibration register */ + __I uint32_t RESERVED1[1]; + __IO uint32_t NMISRC; /*!< NMI Source select register */ + __IO uint32_t ASYNCAPBCTRL; /*!< Asynch APB chiplet control register */ + __I uint32_t RESERVED2[7]; + __IO uint32_t SYSRSTSTAT; /*!< System Reset Stat register */ + __IO uint32_t PRESETCTRL[2]; /*!< Peripheral Reset Ctrl register */ + __IO uint32_t PRESETCTRLSET[2]; /*!< Peripheral Reset Ctrl Set register */ + __IO uint32_t PRESETCTRLCLR[2]; /*!< Peripheral Reset Ctrl Clr register */ + __IO uint32_t PIOPORCAP[2]; /*!< PIO Power-On Reset Capture register */ + __I uint32_t RESERVED3[1]; + __IO uint32_t PIORESCAP[2]; /*!< PIO Pad Reset Capture register */ + __I uint32_t RESERVED4[4]; + __IO uint32_t MAINCLKSELA; /*!< Main Clk sel Source Sel A register */ + __IO uint32_t MAINCLKSELB; /*!< Main Clk sel Source Sel B register */ + __I uint32_t RESERVED5; + __IO uint32_t ADCCLKSEL; /*!< ADC Async Clk Sel register */ + __I uint32_t RESERVED6; + __IO uint32_t CLKOUTSELA; /*!< Clk Out Sel Source A register */ + __IO uint32_t CLKOUTSELB; /*!< Clk Out Sel Source B register */ + __I uint32_t RESERVED7; + __IO uint32_t SYSPLLCLKSEL; /*!< System PLL Clk Selregister */ + __I uint32_t RESERVED8[7]; + __IO uint32_t AHBCLKCTRL[2]; /*!< AHB Peripheral Clk Enable register */ + __IO uint32_t AHBCLKCTRLSET[2]; /*!< AHB Peripheral Clk Enable Set register */ + __IO uint32_t AHBCLKCTRLCLR[2]; /*!< AHB Peripheral Clk Enable Clr register */ + __I uint32_t RESERVED9[2]; + __IO uint32_t SYSTICKCLKDIV; /*!< Systick Clock divider register */ + __I uint32_t RESERVED10[7]; + __IO uint32_t AHBCLKDIV; /*!< Main Clk Divider register */ + __IO uint32_t RESERVED11; + __IO uint32_t ADCCLKDIV; /*!< ADC Async Clk Divider register */ + __IO uint32_t CLKOUTDIV; /*!< Clk Out Divider register */ + __I uint32_t RESERVED12[4]; + __IO uint32_t FREQMECTRL; /*!< Frequency Measure Control register */ + __IO uint32_t FLASHCFG; /*!< Flash Config register */ + __I uint32_t RESERVED13[8]; + __IO uint32_t FIFOCTRL; /*!< VFIFO control register */ + __I uint32_t RESERVED14[14]; + __I uint32_t RESERVED15[1]; + __I uint32_t RESERVED16[2]; + __IO uint32_t RTCOSCCTRL; /*!< RTC Oscillator Control register */ + __I uint32_t RESERVED17[7]; + __IO uint32_t SYSPLLCTRL; /*!< System PLL control register */ + __IO uint32_t SYSPLLSTAT; /*!< PLL status register */ + __IO uint32_t SYSPLLNDEC; /*!< PLL N decoder register */ + __IO uint32_t SYSPLLPDEC; /*!< PLL P decoder register */ + __IO uint32_t SYSPLLSSCTRL[2]; /*!< Spread Spectrum control registers */ + __I uint32_t RESERVED18[18]; + __IO uint32_t PDRUNCFG; /*!< Power Down Run Config register */ + __IO uint32_t PDRUNCFGSET; /*!< Power Down Run Config Set register */ + __IO uint32_t PDRUNCFGCLR; /*!< Power Down Run Config Clr register */ + __I uint32_t RESERVED19[9]; + __IO uint32_t STARTERP[2]; /*!< Start Signal Enable Register */ + __IO uint32_t STARTERSET[2]; /*!< Start Signal Enable Set Register */ + __IO uint32_t STARTERCLR[2]; /*!< Start Signal Enable Clr Register */ + __I uint32_t RESERVED20[42]; + __I uint32_t RESERVED20A[4]; + __I uint32_t RESERVED21[57]; + __IO uint32_t JTAG_IDCODE; + __IO uint32_t DEVICE_ID0; /*!< Boot ROM and die revision register */ + __IO uint32_t DEVICE_ID1; /*!< Boot ROM and die revision register */ +} LPC_SYSCON_T; + +/** + * @brief LPC5410X Asynchronous system configuration register block structure + */ +typedef struct { + __IO uint32_t AYSNCPRESETCTRL; /*!< peripheral reset register */ + __IO uint32_t ASYNCPRESETCTRLSET; /*!< peripheral reset Set register */ + __IO uint32_t ASYNCPRESETCTRLCLR; /*!< peripheral reset Clr register */ + __I uint32_t RESERVED0; + __IO uint32_t ASYNCAPBCLKCTRL; /*!< clk enable register */ + __IO uint32_t ASYNCAPBCLKCTRLSET; /*!< clk enable Set register */ + __IO uint32_t ASYNCAPBCLKCTRLCLR; /*!< clk enable Clr register */ + __I uint32_t RESERVED1; + __IO uint32_t ASYNCAPBCLKSELA; /*!< clk source mux A register */ + __IO uint32_t ASYNCAPBCLKSELB; /*!< clk source mux B register */ + __IO uint32_t ASYNCCLKDIV; /*!< clk div register */ + __I uint32_t RESERVED2; + __IO uint32_t FRGCTRL; /*!< Fraction Rate Generator Ctrl register */ +} LPC_ASYNC_SYSCON_T; + +/** + * System memory remap modes used to remap interrupt vectors + */ +typedef enum CHIP_SYSCON_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_SYSCON_BOOT_MODE_REMAP_T; + +/** + * @brief Re-map interrupt vectors + * @param remap : system memory map value + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_Map(CHIP_SYSCON_BOOT_MODE_REMAP_T remap) +{ + LPC_SYSCON->SYSMEMREMAP = (uint32_t) remap; +} + +/** + * @brief Get system remap setting + * @return System remap setting + */ +STATIC INLINE CHIP_SYSCON_BOOT_MODE_REMAP_T Chip_SYSCON_GetMemoryMap(void) +{ + return (CHIP_SYSCON_BOOT_MODE_REMAP_T) LPC_SYSCON->SYSMEMREMAP; +} + +/** + * @brief Set System tick timer calibration value + * @param sysCalVal : System tick timer calibration value + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_SetSYSTCKCAL(uint32_t sysCalVal) +{ + LPC_SYSCON->SYSTCKCAL = sysCalVal; +} + +/** + * Non-Maskable Interrupt Enable/Disable value + */ +#define SYSCON_NMISRC_M0_ENABLE ((uint32_t) 1 << 30) /*!< Enable the Non-Maskable Interrupt M0 (NMI) source */ +#define SYSCON_NMISRC_M4_ENABLE ((uint32_t) 1 << 31) /*!< Enable the Non-Maskable Interrupt M4 (NMI) source */ + +/** + * @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_SYSCON_EnableNMISource() function to enable the NMI source. + */ +void Chip_SYSCON_SetNMISource(uint32_t intsrc); + +/** + * @brief Enable interrupt used for NMI source + * @return Nothing + */ +void Chip_SYSCON_EnableNMISource(void); + +/** + * @brief Disable interrupt used for NMI source + * @return Nothing + */ +void Chip_SYSCON_DisableNMISource(void); + +/** + * @brief Enable or disable asynchronous APB bridge and subsystem + * @param enable : true to enable, false to disable + * @return Nothing + * @note This bridge must be enabled to access peripherals on the + * associated bridge. + */ +void Chip_SYSCON_Enable_ASYNC_Syscon(bool enable); + +/** + * @brief Set UART Fractional divider value + * @param fmul : Fractional multiplier value + * @param fdiv : Fractional divider value (Must always be 0xFF) + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_SetUSARTFRGCtrl(uint8_t fmul, uint8_t fdiv) +{ + LPC_ASYNC_SYSCON->FRGCTRL = ((uint32_t) fmul << 8) | fdiv; +} + +/** + * System reset status values + */ +#define SYSCON_RST_POR (1 << 0) /*!< POR reset status */ +#define SYSCON_RST_EXTRST (1 << 1) /*!< External reset status */ +#define SYSCON_RST_WDT (1 << 2) /*!< Watchdog reset status */ +#define SYSCON_RST_BOD (1 << 3) /*!< Brown-out detect reset status */ +#define SYSCON_RST_SYSRST (1 << 4) /*!< software system reset status */ + +/** + * @brief Get system reset status + * @return An Or'ed value of SYSCON_RST_* + * @note This function returns the detected reset source(s). + */ +STATIC INLINE uint32_t Chip_SYSCON_GetSystemRSTStatus(void) +{ + return LPC_SYSCON->SYSRSTSTAT; +} + +/** + * @brief Clear system reset status + * @param reset : An Or'ed value of SYSCON_RST_* status to clear + * @return Nothing + * @note This function clears the specified reset source(s). + */ +STATIC INLINE void Chip_SYSCON_ClearSystemRSTStatus(uint32_t reset) +{ + LPC_SYSCON->SYSRSTSTAT = reset; +} + +/** + * Peripheral reset identifiers + */ +typedef enum { + /* Peripheral reset enables for PRESETCTRL0 */ + RESET_FLASH = 7, /*!< Flash controller */ + RESET_FMC, /*!< Flash accelerator */ + RESET_INMUX = 11, /*!< Input mux */ + RESET_IOCON = 13, /*!< IOCON */ + RESET_GPIO0, /*!< GPIO Port 0 */ + RESET_GPIO1, /*!< GPIO Port 1 */ + RESET_PINT = 18, /*!< Pin interrupt */ + RESET_GINT, /*!< Grouped interrupt (GINT) */ + RESET_DMA, /*!< DMA */ + RESET_CRC, /*!< CRC */ + RESET_WWDT, /*!< Watchdog timer */ + RESET_RTC, /*!< RTC */ + RESET_MAILBOX = 26, /*!< Mailbox */ + RESET_ADC0, /*!< ADC0 */ + + /* Peripheral reset enables for PRESETCTRL1 */ + RESET_MRT = 32 + 0, /*!< multi-rate timer */ + RESET_RIT, /*!< Repetitive interrupt timer */ + RESET_SCT0, /*!< SCT0 */ + RESET_FIFO = 32 + 9, /*!< System FIFO */ + RESET_UTICK, /*!< Micro-tick Timer */ + RESET_TIMER2 = 32 + 22, /*!< TIMER2 */ + RESET_TIMER3 = 32 + 26, /*!< TIMER3 */ + RESET_TIMER4, /*!< TIMER4 */ + + /* Async peripheral reset enables for ASYNCPRESETCTRL */ + RESET_USART0 = 128 + 1, /*!< UART0 */ + RESET_USART1, /*!< UART1 */ + RESET_USART2, /*!< UART2 */ + RESET_USART3, /*!< UART3 */ + RESET_I2C0, /*!< I2C0 */ + RESET_I2C1, /*!< I2C1 */ + RESET_I2C2, /*!< I2C2 */ + RESET_SPI0 = 128 + 9, /*!< SPI0 */ + RESET_SPI1, /*!< SPI1 */ + RESET_TIMER0 = 128 + 13, /*!< TIMER0 */ + RESET_TIMER1, /*!< TIMER1 */ + RESET_FRG0 /*!< FRG */ +} CHIP_SYSCON_PERIPH_RESET_T; + +/** + * @brief Resets a peripheral + * @param periph : Peripheral to reset + * @return Nothing + * Will assert and de-assert reset for a peripheral. + */ +void Chip_SYSCON_PeriphReset(CHIP_SYSCON_PERIPH_RESET_T periph); + +/** + * @brief Read POR captured PIO status + * @param port : 0 for port 0 pins, 1 for port 1 pins, 2 for port 2 pins, etc. + * @return captured Power-On-Reset (POR) PIO status + */ +STATIC INLINE uint32_t Chip_SYSCON_GetPORPIOStatus(uint8_t port) +{ + return LPC_SYSCON->PIOPORCAP[port]; +} + +/** + * @brief Read reset captured PIO status + * @param port : 0 for port 0 pins, 1 for port 1 pins, 2 for port 2 pins, etc. + * @return captured reset PIO status + * @note Used when reset other than a Power-On-Reset (POR) occurs. + */ +STATIC INLINE uint32_t Chip_SYSCON_GetResetPIOStatus(uint8_t port) +{ + return LPC_SYSCON->PIORESCAP[port]; +} + +/** + * @brief Starts a frequency measurement cycle + * @return Nothing + * @note This function is meant to be used with the Chip_INMUX_SetFreqMeasRefClock() + * and Chip_INMUX_SetFreqMeasTargClock() functions. + */ +STATIC INLINE void Chip_SYSCON_StartFreqMeas(void) +{ + LPC_SYSCON->FREQMECTRL = 0; + LPC_SYSCON->FREQMECTRL = (1UL << 31); +} + +/** + * @brief Indicates when a frequency measurement cycle is complete + * @return true if a measurement cycle is active, otherwise false + */ +STATIC INLINE bool Chip_SYSCON_IsFreqMeasComplete(void) +{ + return (bool) ((LPC_SYSCON->FREQMECTRL & (1UL << 31)) == 0); +} + +/** + * @brief Returns the raw capture value for a frequency measurement cycle + * @return raw cpature value (this is not a frequency) + */ +STATIC INLINE uint32_t Chip_SYSCON_GetRawFreqMeasCapval(void) +{ + return LPC_SYSCON->FREQMECTRL & 0x3FFF; +} + +/** + * @brief Returns the computed value for a frequency measurement cycle + * @param refClockRate : Reference clock rate used during the frequency measurement cycle + * @return Computed cpature value + */ +uint32_t Chip_SYSCON_GetCompFreqMeas(uint32_t refClockRate); + +/** + * @brief FLASH Access time definitions + */ +typedef enum { + SYSCON_FLASH_1CYCLE = 0, /*!< Flash accesses use 1 CPU clock */ + FLASHTIM_20MHZ_CPU = SYSCON_FLASH_1CYCLE, + SYSCON_FLASH_2CYCLE, /*!< Flash accesses use 2 CPU clocks */ + SYSCON_FLASH_3CYCLE, /*!< Flash accesses use 3 CPU clocks */ + SYSCON_FLASH_4CYCLE, /*!< Flash accesses use 4 CPU clocks */ + SYSCON_FLASH_5CYCLE, /*!< Flash accesses use 5 CPU clocks */ + SYSCON_FLASH_6CYCLE, /*!< Flash accesses use 6 CPU clocks */ + SYSCON_FLASH_7CYCLE, /*!< Flash accesses use 7 CPU clocks */ + SYSCON_FLASH_8CYCLE /*!< Flash accesses use 8 CPU clocks */ +} SYSCON_FLASHTIM_T; + +/** + * @brief Set FLASH memory access time in clocks + * @param clks : Clock cycles for FLASH access + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_SetFLASHAccess(SYSCON_FLASHTIM_T clks) +{ + uint32_t tmp; + + tmp = LPC_SYSCON->FLASHCFG & ~(0xF << 12); + + /* Don't alter lower bits */ + LPC_SYSCON->FLASHCFG = tmp | ((uint32_t) clks << 12); +} + +/** + * @brief System FIFO bit definitions + */ +#define SYSCON_FIFO_U0TXFIFOEN (1 << 0) /*!< USART0 transmitter FIFO enable bit */ +#define SYSCON_FIFO_U1TXFIFOEN (1 << 1) /*!< USART1 transmitter FIFO enable bit */ +#define SYSCON_FIFO_U2TXFIFOEN (1 << 2) /*!< USART2 transmitter FIFO enable bit */ +#define SYSCON_FIFO_U3TXFIFOEN (1 << 3) /*!< USART3 transmitter FIFO enable bit */ +#define SYSCON_FIFO_SPI0TXFIFOEN (1 << 4) /*!< SPI0 transmitter FIFO enable bit */ +#define SYSCON_FIFO_SPI1TXFIFOEN (1 << 5) /*!< SPI1 transmitter FIFO enable bit */ +#define SYSCON_FIFO_U0RXFIFOEN (1 << 8) /*!< USART0 receiver FIFO enable bit */ +#define SYSCON_FIFO_U1RXFIFOEN (1 << 9) /*!< USART1 receiver FIFO enable bit */ +#define SYSCON_FIFO_U2RXFIFOEN (1 << 10) /*!< USART2 receiver FIFO enable bit */ +#define SYSCON_FIFO_U3RXFIFOEN (1 << 11) /*!< USART3 receiver FIFO enable bit */ +#define SYSCON_FIFO_SPI0RXFIFOEN (1 << 12) /*!< SPI0 receiver FIFO enable bit */ +#define SYSCON_FIFO_SPI1RXFIFOEN (1 << 13) /*!< SPI1 receiver FIFO enable bit */ + +/** + * @brief Enable System FIFO(s) for a peripheral + * @param enMask : Or'ed bits or type SYSCON_FIFO_* for enabling system FIFOs + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_EnableSysFIFO(uint32_t enMask) +{ + LPC_SYSCON->FIFOCTRL |= enMask; +} + +/** + * @brief Disable System FIFO(s) for a peripheral + * @param disMask : Or'ed bits or type SYSCON_FIFO_* for disabling system FIFOs + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_DisableSysFIFO(uint32_t disMask) +{ + LPC_SYSCON->FIFOCTRL &= ~disMask; +} + +/** + * Power control definition bits (0 = powered, 1 = powered down) + */ +#define SYSCON_PDRUNCFG_PD_IRC_OSC (1 << 3) /*!< IRC oscillator output */ +#define SYSCON_PDRUNCFG_PD_IRC (1 << 4) /*!< IRC oscillator */ +#define SYSCON_PDRUNCFG_PD_FLASH (1 << 5) /*!< Flash memory */ +#define SYSCON_PDRUNCFG_PD_BOD_RST (1 << 7) /*!< Brown-out Detect reset */ +#define SYSCON_PDRUNCFG_PD_BOD_INTR (1 << 8) /*!< Brown-out Detect interrupt */ +#define SYSCON_PDRUNCFG_PD_ADC0 (1 << 10) /*!< ADC0 */ +#define SYSCON_PDRUNCFG_PD_SRAM0A (1 << 13) /*!< First 8 kB of SRAM0 */ +#define SYSCON_PDRUNCFG_PD_SRAM0B (1 << 14) /*!< Remaining portion of SRAM0 */ +#define SYSCON_PDRUNCFG_PD_SRAM1 (1 << 15) /*!< SRAM1 */ +#define SYSCON_PDRUNCFG_PD_SRAM2 (1 << 16) /*!< SRAM2 */ +#define SYSCON_PDRUNCFG_PD_ROM (1 << 17) /*!< ROM */ +#define SYSCON_PDRUNCFG_PD_VDDA_ENA (1 << 19) /*!< Vdda to the ADC, must be enabled for the ADC to work */ +#define SYSCON_PDRUNCFG_PD_WDT_OSC (1 << 20) /*!< Watchdog oscillator */ +#define SYSCON_PDRUNCFG_PD_SYS_PLL (1 << 22) /*!< PLL0 */ +#define SYSCON_PDRUNCFG_PD_VREFP (1 << 23) /*!< Vrefp to the ADC, must be enabled for the ADC to work */ +#define SYSCON_PDRUNCFG_PD_32K_OSC (1 << 24) /*!< 32 kHz RTC oscillator */ + +/** + * @brief Power up one or more blocks or peripherals + * @return OR'ed values of SYSCON_PDRUNCFG_* values + * @note A high state indicates the peripheral is powered down. + */ +STATIC INLINE uint32_t Chip_SYSCON_GetPowerStates(void) +{ + return LPC_SYSCON->PDRUNCFG; +} + +/** + * @brief Power down one or more blocks or peripherals + * @param powerdownmask : OR'ed values of SYSCON_PDRUNCFG_* values + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_PowerDown(uint32_t powerdownmask) +{ + /* Disable peripheral states by setting high */ + LPC_SYSCON->PDRUNCFGSET = powerdownmask; +} + +/** + * @brief Power up one or more blocks or peripherals + * @param powerupmask : OR'ed values of SYSCON_PDRUNCFG_* values + * @return Nothing + */ +void Chip_SYSCON_PowerUp(uint32_t powerupmask); + +/** + * Start enable enumerations - for enabling and disabling peripheral wakeup + */ +typedef enum { + SYSCON_STARTER_WWDT = 0, + SYSCON_STARTER_BOD, + SYSCON_STARTER_DMA = 3, + SYSCON_STARTER_GINT0, + SYSCON_STARTER_PINT0, + SYSCON_STARTER_PINT1, + SYSCON_STARTER_PINT2, + SYSCON_STARTER_PINT3, + SYSCON_STARTER_UTICK, + SYSCON_STARTER_MRT, + SYSCON_STARTER_TIMER0, + SYSCON_STARTER_TIMER1, + SYSCON_STARTER_TIMER2, + SYSCON_STARTER_TIMER3, + SYSCON_STARTER_TIMER4, + SYSCON_STARTER_SCT0, + SYSCON_STARTER_USART0, + SYSCON_STARTER_USART1, + SYSCON_STARTER_USART2, + SYSCON_STARTER_USART3, + SYSCON_STARTER_I2C0, + SYSCON_STARTER_I2C1, + SYSCON_STARTER_I2C2, + SYSCON_STARTER_SPI0, + SYSCON_STARTER_SPI1, + SYSCON_STARTER_ADC0_SEQA, + SYSCON_STARTER_ADC0_SEQB, + SYSCON_STARTER_ADC0_THCMP, + SYSCON_STARTER_RTC, + SYSCON_STARTER_MAILBOX = 31, + /* For M4 only */ + SYSCON_STARTER_GINT1 = 32 + 0, + SYSCON_STARTER_PINT4, + SYSCON_STARTER_PINT5, + SYSCON_STARTER_PINT6, + SYSCON_STARTER_PINT7, + SYSCON_STARTER_RIT = 32 + 8, +} CHIP_SYSCON_WAKEUP_T; + +/** + * @brief Enables a pin's (PINT) wakeup logic + * @param periphId : Peripheral identifier + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_EnableWakeup(CHIP_SYSCON_WAKEUP_T periphId) +{ + uint32_t pid = (uint32_t) periphId; + + if (pid < 32) { + LPC_SYSCON->STARTERSET[0] = (1 << pid); + } + else { + LPC_SYSCON->STARTERSET[1] = (1 << (pid - 32)); + } +} + +/** + * @brief Disables peripheral's wakeup logic + * @param periphId : Peripheral identifier + * @return Nothing + */ +STATIC INLINE void Chip_SYSCON_DisableWakeup(CHIP_SYSCON_WAKEUP_T periphId) +{ + uint32_t pid = (uint32_t) periphId; + + if (pid < 32) { + LPC_SYSCON->STARTERCLR[0] = (1 << pid); + } + else { + LPC_SYSCON->STARTERCLR[1] = (1 << (pid - 32)); + } +} + +/** + * @brief Return the device ID + * @return Device ID + */ +STATIC INLINE uint32_t Chip_SYSCON_GetDeviceID(void) +{ + return LPC_SYSCON->DEVICE_ID0; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSCON_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sysinit_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sysinit_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..06b9170f9ec723762b958d35b2264ac9e34509ba --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/sysinit_5410x.c @@ -0,0 +1,169 @@ +/* + * @brief LPC5410X Chip specific SystemInit + * + * @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 + ****************************************************************************/ + +/* Sets the best FLASH clock arte for the passed frequency */ +static void setupFlashClocks(uint32_t freq) +{ + /* v17.0 ROM support only - coarse FLASH clocking timing. + FLASH access is setup based on voltage for v17.1 and later ROMs + as part of the power library. */ + if (Chip_POWER_GetROMVersion() == LPC5410X_ROMVER_0) { + if (freq < 20000000) { + Chip_SYSCON_SetFLASHAccess(SYSCON_FLASH_1CYCLE); + } + else if (freq < 48000000) { + Chip_SYSCON_SetFLASHAccess(SYSCON_FLASH_2CYCLE); + } + else if (freq < 72000000) { + Chip_SYSCON_SetFLASHAccess(SYSCON_FLASH_3CYCLE); + } + else { + Chip_SYSCON_SetFLASHAccess(SYSCON_FLASH_4CYCLE); + } + } +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Clock and PLL initialization based on the internal oscillator */ +void Chip_SetupIrcClocking(uint32_t iFreq) +{ + PLL_CONFIG_T pllConfig; + PLL_SETUP_T pllSetup; + PLL_ERROR_T pllError; + + /* Turn on the IRC by clearing the power down bit */ + Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_IRC_OSC | SYSCON_PDRUNCFG_PD_IRC); + + /* Select the PLL input to the IRC */ + Chip_Clock_SetSystemPLLSource(SYSCON_PLLCLKSRC_IRC); + + /* Setup FLASH access û½øÈ¥??*/ + setupFlashClocks(iFreq); + + /* Power down PLL to change the PLL divider ratio */ + Chip_SYSCON_PowerDown(SYSCON_PDRUNCFG_PD_SYS_PLL); + + /* Setup PLL configuration */ + pllConfig.desiredRate = iFreq; + pllConfig.InputRate = 0; + pllConfig.flags = PLL_CONFIGFLAG_FORCENOFRACT; + pllError = Chip_Clock_SetupPLLData(&pllConfig, &pllSetup); + if (pllError == PLL_ERROR_SUCCESS) { + pllSetup.flags = PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_ADGVOLT; + pllError = Chip_Clock_SetupSystemPLLPrec(&pllSetup); + } + + /* Set system clock divider to 1 */ + Chip_Clock_SetSysClockDiv(1); + + /* 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(SYSCON_MAINCLKSRC_PLLOUT); + + /* ASYSNC SYSCON needs to be on or all serial peripheral won't work. + Be careful if PLL is used or not, ASYNC_SYSCON source needs to be + selected carefully. */ + Chip_SYSCON_Enable_ASYNC_Syscon(true); + Chip_Clock_SetAsyncSysconClockDiv(1); + Chip_Clock_SetAsyncSysconClockSource(SYSCON_ASYNC_IRC); +} + +/* Clock and PLL initialization based on the external clock input */ +void Chip_SetupExtInClocking(uint32_t iFreq) +{ + PLL_CONFIG_T pllConfig; + PLL_SETUP_T pllSetup; + PLL_ERROR_T pllError; + + /* IOCON clock left on, this is needed is CLKIN is used. */ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON); + + /* Select external clock input pin */ + Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 22, (IOCON_MODE_PULLUP | + IOCON_FUNC1 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF)); + + /* Select the PLL input to the EXT clock input */ + Chip_Clock_SetSystemPLLSource(SYSCON_PLLCLKSRC_CLKIN); + + /* Setup FLASH access */ + setupFlashClocks(iFreq); + + /* Power down PLL to change the PLL divider ratio */ + Chip_SYSCON_PowerDown(SYSCON_PDRUNCFG_PD_SYS_PLL); + + /* Setup PLL configuration */ + pllConfig.desiredRate = iFreq; + pllConfig.InputRate = 0; + pllConfig.flags = PLL_CONFIGFLAG_FORCENOFRACT; + pllError = Chip_Clock_SetupPLLData(&pllConfig, &pllSetup); + if (pllError == PLL_ERROR_SUCCESS) { + pllSetup.flags = PLL_SETUPFLAG_WAITLOCK | PLL_SETUPFLAG_ADGVOLT; + pllError = Chip_Clock_SetupSystemPLLPrec(&pllSetup); + } + + /* Set system clock divider to 1 */ + Chip_Clock_SetSysClockDiv(1); + + /* 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(SYSCON_MAINCLKSRC_PLLOUT); + + /* ASYSNC SYSCON needs to be on or all serial peripheral won't work. + Be careful if PLL is used or not, ASYNC_SYSCON source needs to be + selected carefully. */ + Chip_SYSCON_Enable_ASYNC_Syscon(true); + Chip_Clock_SetAsyncSysconClockDiv(1); + Chip_Clock_SetAsyncSysconClockSource(SYSCON_ASYNC_IRC); +} + +/* Set up and initialize hardware prior to call to main */ +void Chip_SystemInit(void) +{ + /* Initial internal clocking @100MHz */ + Chip_SetupIrcClocking(100000000); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..7938a1988aa9e300c4225bef563ec815036f71ba --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.c @@ -0,0 +1,133 @@ +/* + * @brief LPC5410X 32-bit Timer/PWM 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 + ****************************************************************************/ + +struct TBASE_TO_TMRBITS { + uint32_t base; + uint8_t clockID; + uint8_t resetID; +}; + +#define LAST_TIMER (4) +static const struct TBASE_TO_TMRBITS tbaseToTimerIDs[LAST_TIMER + 1] = { + {LPC_TIMER0_BASE, (uint8_t) SYSCON_CLOCK_TIMER0, (uint8_t) RESET_TIMER0}, + {LPC_TIMER1_BASE, (uint8_t) SYSCON_CLOCK_TIMER1, (uint8_t) RESET_TIMER1}, + {LPC_TIMER2_BASE, (uint8_t) SYSCON_CLOCK_TIMER2, (uint8_t) RESET_TIMER2}, + {LPC_TIMER3_BASE, (uint8_t) SYSCON_CLOCK_TIMER3, (uint8_t) RESET_TIMER3}, + {LPC_TIMER4_BASE, (uint8_t) SYSCON_CLOCK_TIMER4, (uint8_t) RESET_TIMER4} +}; + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Return index into tbaseToTimerIDs for timers 0-4 */ +static int GetClockID(LPC_TIMER_T *pTMR) +{ + int timerId = LAST_TIMER; + + while (timerId >= 0) { + if (pTMR == (LPC_TIMER_T *) tbaseToTimerIDs[timerId].base) { + return timerId; + } + + timerId--; + } + + /* Waill return timer 0 if no timer match */ + return 0; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize a timer */ +void Chip_TIMER_Init(LPC_TIMER_T *pTMR) +{ + int clockId = GetClockID(pTMR); + + Chip_Clock_EnablePeriphClock((CHIP_SYSCON_CLOCK_T) tbaseToTimerIDs[clockId].clockID); + Chip_SYSCON_PeriphReset((CHIP_SYSCON_PERIPH_RESET_T) tbaseToTimerIDs[clockId].resetID); +} + +/* Shutdown a timer */ +void Chip_TIMER_DeInit(LPC_TIMER_T *pTMR) +{ + int clockId = GetClockID(pTMR); + + Chip_Clock_DisablePeriphClock((CHIP_SYSCON_CLOCK_T) tbaseToTimerIDs[clockId].clockID); +} + +/* Resets the timer counter and prescale counts to 0 */ +void Chip_TIMER_Reset(LPC_TIMER_T *pTMR) +{ + uint32_t reg; + + /* Disable timer, set terminal count to non-0 */ + reg = pTMR->TCR; + pTMR->TCR = 0; + pTMR->TC = 1; + + /* Reset timer counter */ + pTMR->TCR = TIMER_RESET; + + /* Wait for terminal count to clear */ + while (pTMR->TC != 0) {} + + /* Restore timer state */ + pTMR->TCR = reg; +} + +/* Sets external match control (MATn.matchnum) pin control */ +void Chip_TIMER_ExtMatchControlSet(LPC_TIMER_T *pTMR, int8_t initial_state, + TIMER_PIN_MATCH_STATE_T matchState, int8_t matchnum) +{ + uint32_t mask, reg; + + /* Clear bits corresponding to selected match register */ + mask = (1 << matchnum) | (0x03 << (4 + (matchnum * 2))); + /* Also mask reserved bits */ + reg = (pTMR->EMR & TIMER_EMR_MASK) & ~mask; + + /* Set new configuration for selected match register */ + pTMR->EMR = reg | (((uint32_t) initial_state) << matchnum) | + (((uint32_t) matchState) << (4 + (matchnum * 2))); +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..59bbee9083c657f57190e2949ca3a0ac898d89c5 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/timer_5410x.h @@ -0,0 +1,456 @@ +/* + * @brief LPC5410X 32-bit Timer/PWM 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 __TIMER_5410X_H_ +#define __TIMER_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup TIMER_5410X CHIP: LPC5410X 32-bit Timer driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief 32-bit Standard timer register block structure + */ +typedef struct { /*!< TIMERn Structure */ + __IO uint32_t IR; /*!< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */ + __IO uint32_t TCR; /*!< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */ + __IO uint32_t TC; /*!< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled through the TCR. */ + __IO uint32_t PR; /*!< Prescale Register. The Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC. */ + __IO uint32_t PC; /*!< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */ + __IO uint32_t MCR; /*!< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */ + __IO uint32_t MR[4]; /*!< Match Register. MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */ + __IO uint32_t CCR; /*!< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */ + __IO uint32_t CR[4]; /*!< Capture Register. CR is loaded with the value of TC when there is an event on the CAPn.0 input. */ + __IO uint32_t EMR; /*!< External Match Register. The EMR controls the external match pins MATn.0-3 (MAT0.0-3 and MAT1.0-3 respectively). */ + __I uint32_t RESERVED0[12]; + __IO uint32_t CTCR; /*!< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */ + __IO uint32_t PWMC; +} LPC_TIMER_T; + +/** Macro to clear interrupt pending */ +#define TIMER_IR_CLR(n) _BIT(n) + +/** Macro for getting a timer match interrupt bit */ +#define TIMER_MATCH_INT(n) (_BIT((n) & 0x0F)) +/** Macro for getting a capture event interrupt bit */ +#define TIMER_CAP_INT(n) (_BIT((((n) & 0x0F) + 4))) + +/** Timer/counter enable bit */ +#define TIMER_ENABLE ((uint32_t) (1 << 0)) +/** Timer/counter reset bit */ +#define TIMER_RESET ((uint32_t) (1 << 1)) +/** Timer Control register Mask */ +#define TIMER_CTRL_MASK ((uint32_t) 0x03) + +/** Bit location for interrupt on MRx match, n = 0 to 3 */ +#define TIMER_INT_ON_MATCH(n) (_BIT(((n) * 3))) +/** Bit location for reset on MRx match, n = 0 to 3 */ +#define TIMER_RESET_ON_MATCH(n) (_BIT((((n) * 3) + 1))) +/** Bit location for stop on MRx match, n = 0 to 3 */ +#define TIMER_STOP_ON_MATCH(n) (_BIT((((n) * 3) + 2))) +/** Match Control register Mask */ +#define TIMER_MCR_MASK ((uint32_t) 0x0FFF) + +/** Bit location for CAP.n on CRx rising edge, n = 0 to 3 */ +#define TIMER_CAP_RISING(n) (_BIT(((n) * 3))) +/** Bit location for CAP.n on CRx falling edge, n = 0 to 3 */ +#define TIMER_CAP_FALLING(n) (_BIT((((n) * 3) + 1))) +/** Bit location for CAP.n on CRx interrupt enable, n = 0 to 3 */ +#define TIMER_INT_ON_CAP(n) (_BIT((((n) * 3) + 2))) +/** Capture Control register Mask */ +#define TIMER_CCR_MASK ((uint32_t) 0x0FFF) +/** External Match register Mask */ +#define TIMER_EMR_MASK ((uint32_t) 0x0FFF) +/** Counter Control register Mask */ +#define TIMER_CTCR_MASK ((uint32_t) 0x0F) + +/** + * @brief Initialize a timer + * @param pTMR : Pointer to timer IP register address + * @return Nothing + */ +void Chip_TIMER_Init(LPC_TIMER_T *pTMR); + +/** + * @brief Shutdown a timer + * @param pTMR : Pointer to timer IP register address + * @return Nothing + */ +void Chip_TIMER_DeInit(LPC_TIMER_T *pTMR); + +/** + * @brief Determine if a match interrupt is pending + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match interrupt number to check + * @return false if the interrupt is not pending, otherwise true + * @note Determine if the match interrupt for the passed timer and match + * counter is pending. + */ +STATIC INLINE bool Chip_TIMER_MatchPending(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + return (bool) ((pTMR->IR & TIMER_MATCH_INT(matchnum)) != 0); +} + +/** + * @brief Determine if a capture interrupt is pending + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture interrupt number to check + * @return false if the interrupt is not pending, otherwise true + * @note Determine if the capture interrupt for the passed capture pin is + * pending. + */ +STATIC INLINE bool Chip_TIMER_CapturePending(LPC_TIMER_T *pTMR, int8_t capnum) +{ + return (bool) ((pTMR->IR & TIMER_CAP_INT(capnum)) != 0); +} + +/** + * @brief Clears a (pending) match interrupt + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match interrupt number to clear + * @return Nothing + * @note Clears a pending timer match interrupt. + */ +STATIC INLINE void Chip_TIMER_ClearMatch(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->IR = TIMER_IR_CLR(matchnum); +} + +/** + * @brief Clears a (pending) capture interrupt + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture interrupt number to clear + * @return Nothing + * @note Clears a pending timer capture interrupt. + */ +STATIC INLINE void Chip_TIMER_ClearCapture(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->IR = (0x10 << capnum); +} + +/** + * @brief Enables the timer (starts count) + * @param pTMR : Pointer to timer IP register address + * @return Nothing + * @note Enables the timer to start counting. + */ +STATIC INLINE void Chip_TIMER_Enable(LPC_TIMER_T *pTMR) +{ + pTMR->TCR = (pTMR->TCR & TIMER_CTRL_MASK) | TIMER_ENABLE; +} + +/** + * @brief Disables the timer (stops count) + * @param pTMR : Pointer to timer IP register address + * @return Nothing + * @note Disables the timer to stop counting. + */ +STATIC INLINE void Chip_TIMER_Disable(LPC_TIMER_T *pTMR) +{ + pTMR->TCR = (pTMR->TCR & TIMER_CTRL_MASK) & ~TIMER_ENABLE; +} + +/** + * @brief Returns the current timer count + * @param pTMR : Pointer to timer IP register address + * @return Current timer terminal count value + * @note Returns the current timer terminal count. + */ +STATIC INLINE uint32_t Chip_TIMER_ReadCount(LPC_TIMER_T *pTMR) +{ + return pTMR->TC; +} + +/** + * @brief Returns the current prescale count + * @param pTMR : Pointer to timer IP register address + * @return Current timer prescale count value + * @note Returns the current prescale count. + */ +STATIC INLINE uint32_t Chip_TIMER_ReadPrescale(LPC_TIMER_T *pTMR) +{ + return pTMR->PC; +} + +/** + * @brief Sets the prescaler value + * @param pTMR : Pointer to timer IP register address + * @param prescale : Prescale value to set the prescale register to + * @return Nothing + * @note Sets the prescale count value. + */ +STATIC INLINE void Chip_TIMER_PrescaleSet(LPC_TIMER_T *pTMR, uint32_t prescale) +{ + pTMR->PR = prescale; +} + +/** + * @brief Sets a timer match value + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer to set match count for + * @param matchval : Match value for the selected match count + * @return Nothing + * @note Sets one of the timer match values. + */ +STATIC INLINE void Chip_TIMER_SetMatch(LPC_TIMER_T *pTMR, int8_t matchnum, uint32_t matchval) +{ + pTMR->MR[matchnum] = matchval; +} + +/** + * @brief Reads a capture register + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture register to read + * @return The selected capture register value + * @note Returns the selected capture register value. + */ +STATIC INLINE uint32_t Chip_TIMER_ReadCapture(LPC_TIMER_T *pTMR, int8_t capnum) +{ + return pTMR->CR[capnum]; +} + +/** + * @brief Resets the timer terminal and prescale counts to 0 + * @param pTMR : Pointer to timer IP register address + * @return Nothing + */ +void Chip_TIMER_Reset(LPC_TIMER_T *pTMR); + +/** + * @brief Enables a match interrupt that fires when the terminal count + * matches the match counter value. + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_MatchEnableInt(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) | TIMER_INT_ON_MATCH(matchnum); +} + +/** + * @brief Disables a match interrupt for a match counter. + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_MatchDisableInt(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) & ~TIMER_INT_ON_MATCH(matchnum); +} + +/** + * @brief For the specific match counter, enables reset of the terminal count register when a match occurs + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_ResetOnMatchEnable(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) | TIMER_RESET_ON_MATCH(matchnum); +} + +/** + * @brief For the specific match counter, disables reset of the terminal count register when a match occurs + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_ResetOnMatchDisable(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) & ~TIMER_RESET_ON_MATCH(matchnum); +} + +/** + * @brief Enable a match timer to stop the terminal count when a + * match count equals the terminal count. + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_StopOnMatchEnable(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) | TIMER_STOP_ON_MATCH(matchnum); +} + +/** + * @brief Disable stop on match for a match timer. Disables a match timer + * to stop the terminal count when a match count equals the terminal count. + * @param pTMR : Pointer to timer IP register address + * @param matchnum : Match timer, 0 to 3 + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_StopOnMatchDisable(LPC_TIMER_T *pTMR, int8_t matchnum) +{ + pTMR->MCR = (pTMR->MCR & TIMER_MCR_MASK) & ~TIMER_STOP_ON_MATCH(matchnum); +} + +/** + * @brief Enables capture on on rising edge of selected CAP signal for the + * selected capture register, enables the selected CAPn.capnum signal to load + * the capture register with the terminal coount on a rising edge. + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureRisingEdgeEnable(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) | TIMER_CAP_RISING(capnum); +} + +/** + * @brief Disables capture on on rising edge of selected CAP signal. For the + * selected capture register, disables the selected CAPn.capnum signal to load + * the capture register with the terminal coount on a rising edge. + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureRisingEdgeDisable(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) & ~TIMER_CAP_RISING(capnum); +} + +/** + * @brief Enables capture on on falling edge of selected CAP signal. For the + * selected capture register, enables the selected CAPn.capnum signal to load + * the capture register with the terminal coount on a falling edge. + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureFallingEdgeEnable(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) | TIMER_CAP_FALLING(capnum); +} + +/** + * @brief Disables capture on on falling edge of selected CAP signal. For the + * selected capture register, disables the selected CAPn.capnum signal to load + * the capture register with the terminal coount on a falling edge. + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureFallingEdgeDisable(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) & ~TIMER_CAP_FALLING(capnum); +} + +/** + * @brief Enables interrupt on capture of selected CAP signal. For the + * selected capture register, an interrupt will be generated when the enabled + * rising or falling edge on CAPn.capnum is detected. + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureEnableInt(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) | TIMER_INT_ON_CAP(capnum); +} + +/** + * @brief Disables interrupt on capture of selected CAP signal + * @param pTMR : Pointer to timer IP register address + * @param capnum : Capture signal/register to use + * @return Nothing + */ +STATIC INLINE void Chip_TIMER_CaptureDisableInt(LPC_TIMER_T *pTMR, int8_t capnum) +{ + pTMR->CCR = (pTMR->CCR & TIMER_CCR_MASK) & ~TIMER_INT_ON_CAP(capnum); +} + +/** + * @brief Standard timer initial match pin state and change state + */ +typedef enum IP_TIMER_PIN_MATCH_STATE { + TIMER_EXTMATCH_DO_NOTHING = 0, /*!< Timer match state does nothing on match pin */ + TIMER_EXTMATCH_CLEAR = 1, /*!< Timer match state sets match pin low */ + TIMER_EXTMATCH_SET = 2, /*!< Timer match state sets match pin high */ + TIMER_EXTMATCH_TOGGLE = 3 /*!< Timer match state toggles match pin */ +} TIMER_PIN_MATCH_STATE_T; + +/** + * @brief Sets external match control (MATn.matchnum) pin control. For the pin + * selected with matchnum, sets the function of the pin that occurs on + * a terminal count match for the match count. + * @param pTMR : Pointer to timer IP register address + * @param initial_state : Initial state of the pin, high(1) or low(0) + * @param matchState : Selects the match state for the pin + * @param matchnum : MATn.matchnum signal to use + * @return Nothing + * @note For the pin selected with matchnum, sets the function of the pin that occurs on + * a terminal count match for the match count. + */ +void Chip_TIMER_ExtMatchControlSet(LPC_TIMER_T *pTMR, int8_t initial_state, + TIMER_PIN_MATCH_STATE_T matchState, int8_t matchnum); + +/** + * @brief Standard timer clock and edge for count source + */ +typedef enum IP_TIMER_CAP_SRC_STATE { + TIMER_CAPSRC_RISING_PCLK = 0, /*!< Timer ticks on PCLK rising edge */ + TIMER_CAPSRC_RISING_CAPN = 1, /*!< Timer ticks on CAPn.x rising edge */ + TIMER_CAPSRC_FALLING_CAPN = 2, /*!< Timer ticks on CAPn.x falling edge */ + TIMER_CAPSRC_BOTH_CAPN = 3 /*!< Timer ticks on CAPn.x both edges */ +} TIMER_CAP_SRC_STATE_T; + +/** + * @brief Sets timer count source and edge with the selected passed from CapSrc. + * If CapSrc selected a CAPn pin, select the specific CAPn pin with the capnum value. + * @param pTMR : Pointer to timer IP register address + * @param capSrc : timer clock source and edge + * @param capnum : CAPn.capnum pin to use (0 - 2) + * @return Nothing + * @note If CapSrc selected a CAPn pin, select the specific CAPn pin with the capnum value. + */ +STATIC INLINE void Chip_TIMER_TIMER_SetCountClockSrc(LPC_TIMER_T *pTMR, + TIMER_CAP_SRC_STATE_T capSrc, + int8_t capnum) +{ + pTMR->CTCR = (pTMR->CTCR & ~TIMER_CTCR_MASK) | ((uint32_t) capSrc | ((uint32_t) capnum) << 2); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIMER_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..a52fb3e48837d1df0540064623d813ebc41cdf4c --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.c @@ -0,0 +1,73 @@ +/* + * @brief LPC5410X UTICK chip 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Setup UTICK */ +void Chip_UTICK_SetTick(LPC_UTICK_T *pUTICK, uint32_t tick_value, bool repeat) +{ + if (repeat) { + tick_value |= UTICK_CTRL_REPEAT; + } + + pUTICK->CTRL = tick_value; +} + +/* Setup UTICK for the passed delay */ +void Chip_UTICK_SetDelayMs(LPC_UTICK_T *pUTICK, uint32_t delayMs, bool repeat) +{ + uint32_t tick_value = (delayMs * Chip_Clock_GetWDTOSCRate()) / 1000; + + if (repeat) { + tick_value |= UTICK_CTRL_REPEAT; + } + else { + tick_value &= ~UTICK_CTRL_REPEAT; + } + + pUTICK->CTRL = tick_value; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..8053dea6c785ad8a2d40f4319935ab1af38e0826 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/utick_5410x.h @@ -0,0 +1,155 @@ +/* + * @brief LPC5410X Micro Tick chip 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 __UTICK_5410X_H_ +#define __UTICK_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup UTICK_5410X CHIP: LPC5410X Micro Tick driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @brief Micro Tick register block structure + */ +typedef struct { + __IO uint32_t CTRL; /*!< UTick Control register */ + __IO uint32_t STATUS; /*!< UTick Status register */ +} LPC_UTICK_T; + +/** + * @brief UTick register definitions + */ +/** UTick repeat delay bit */ +#define UTICK_CTRL_REPEAT ((uint32_t) 1UL << 31) +/** UTick Delay Value Mask */ +#define UTICK_CTRL_DELAY_MASK ((uint32_t) 0x7FFFFFFF) +/** UTick Interrupt Status bit */ +#define UTICK_STATUS_INTR ((uint32_t) 1 << 0) +/** UTick Active Status bit */ +#define UTICK_STATUS_ACTIVE ((uint32_t) 1 << 1) +/** UTick Status Register Mask */ +#define UTICK_STATUS_MASK ((uint32_t) 0x03) + +/** + * @brief Initialize the UTICK peripheral + * @param pUTICK : UTICK peripheral selected + * @return Nothing + */ +STATIC INLINE void Chip_UTICK_Init(LPC_UTICK_T *pUTICK) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_UTICK); + Chip_SYSCON_PeriphReset(RESET_UTICK); +} + +/** + * @brief De-initialize the UTICK peripheral + * @param pUTICK : UTICK peripheral selected + * @return Nothing + */ +STATIC INLINE void Chip_UTICK_DeInit(LPC_UTICK_T *pUTICK) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_UTICK); +} + +/** + * @brief Setup UTICK + * @param pUTICK : The base address of UTICK block + * @param tick_value : Tick value, should not exceed UTICK_CTRL_DELAY_MASK + * @param repeat : If true then delay repeats continuously else it is one time + * @return Nothing + */ +void Chip_UTICK_SetTick(LPC_UTICK_T *pUTICK, uint32_t tick_value, bool repeat); + +/** + * @brief Setup UTICK for the passed delay (in mS) + * @param pUTICK : The base address of UTICK block + * @param delayMs : Delay value in mS (Maximum is 1000mS) + * @param repeat : If true then delay repeats continuously else it is one time + * @return Nothing + * @note The WDT oscillator runs at about 500KHz, so delays in uS won't be + * too accurate. + */ +void Chip_UTICK_SetDelayMs(LPC_UTICK_T *pUTICK, uint32_t delayMs, bool repeat); + +/** + * @brief Read UTICK Value + * @param pUTICK : The base address of UTICK block + * @return Current tick value + */ +STATIC INLINE uint32_t Chip_UTICK_GetTick(LPC_UTICK_T *pUTICK) +{ + return pUTICK->CTRL & UTICK_CTRL_DELAY_MASK; +} + +/** + * @brief Halt UTICK timer + * @param pUTICK : The base address of UTICK block + * @return Nothing + */ +STATIC INLINE void Chip_UTICK_Halt(LPC_UTICK_T *pUTICK) +{ + pUTICK->CTRL = 0; +} + +/** + * @brief Returns the status of UTICK + * @param pUTICK : The base address of UTICK block + * @return Micro tick timer status register value + */ +STATIC INLINE uint32_t Chip_UTICK_GetStatus(LPC_UTICK_T *pUTICK) +{ + return pUTICK->STATUS; +} + +/** + * @brief Clears UTICK Interrupt flag + * @param pUTICK : The base address of UTICK block + * @return Nothing + */ +STATIC INLINE void Chip_UTICK_ClearInterrupt(LPC_UTICK_T *pUTICK) +{ + pUTICK->STATUS = UTICK_STATUS_INTR; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __UTICK_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.c new file mode 100644 index 0000000000000000000000000000000000000000..a1a6b862b5317a57ec64660cc8e137834b10e83d --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.c @@ -0,0 +1,73 @@ +/* + * @brief LPC5410X WWDT chip 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 + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the Watchdog timer */ +void Chip_WWDT_Init(LPC_WWDT_T *pWWDT) +{ + Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_WWDT); + Chip_SYSCON_PeriphReset(RESET_WWDT); + + /* Disable watchdog */ + pWWDT->MOD = 0; + pWWDT->TC = 0xFF; + pWWDT->WARNINT = 0x3FF; + pWWDT->WINDOW = 0xFFFFFF; +} + +/* 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; + } + /* Interrupt flag is cleared by writing a 1 */ + if (status & WWDT_WDMOD_WDINT) { + pWWDT->MOD = (pWWDT->MOD & WWDT_WDMOD_BITMASK) | WWDT_WDMOD_WDINT; + } +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.h new file mode 100644 index 0000000000000000000000000000000000000000..1416ee5c7ffc3d591e0644228db9b155fd060061 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/wwdt_5410x.h @@ -0,0 +1,244 @@ +/* + * @brief LPC5410X WWDT chip 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 __WWDT_5410X_H_ +#define __WWDT_5410X_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup LPC_WWDT CHIP: LPC5410X Windowed Watchdog driver + * @ingroup CHIP_5410X_DRIVERS + * @{ + */ + +/** + * @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; + +/** + * @brief Watchdog Mode register definitions + */ +/** Watchdog Mode Bitmask */ +#define WWDT_WDMOD_BITMASK ((uint32_t) 0x3F) +/** WWDT enable bit */ +#define WWDT_WDMOD_WDEN ((uint32_t) (1 << 0)) +/** WWDT reset enable bit */ +#define WWDT_WDMOD_WDRESET ((uint32_t) (1 << 1)) +/** WWDT time-out flag bit */ +#define WWDT_WDMOD_WDTOF ((uint32_t) (1 << 2)) +/** WWDT warning interrupt flag bit */ +#define WWDT_WDMOD_WDINT ((uint32_t) (1 << 3)) +/** WWDT Protect flag bit */ +#define WWDT_WDMOD_WDPROTECT ((uint32_t) (1 << 4)) +/** WWDT lock bit */ +#define WWDT_WDMOD_LOCK ((uint32_t) (1 << 5)) + +/** + * @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 + */ +STATIC INLINE void Chip_WWDT_DeInit(LPC_WWDT_T *pWWDT) +{ + Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_WWDT); +} + +/** + * @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. + * Note that if WWDT registers are modified in an interrupt then it is a good + * idea to prevent those interrupts when writing the feed sequence. + */ +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 Get WWDT warning interrupt + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return WWDT warning interrupt + */ +STATIC INLINE uint32_t Chip_WWDT_GetWarning(LPC_WWDT_T *pWWDT) +{ + return pWWDT->WARNINT; +} + +/** + * @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 Get WWDT window time + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return WWDT window time + */ +STATIC INLINE uint32_t Chip_WWDT_GetWindow(LPC_WWDT_T *pWWDT) +{ + return pWWDT->WINDOW; +} + +/** + * @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 = (pWWDT->MOD & WWDT_WDMOD_BITMASK) | options; +} + +/** + * @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_5410X_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/error.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/error.h new file mode 100644 index 0000000000000000000000000000000000000000..517e7a4956f1c58510c3a676fb350d873f05112a --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/error.h @@ -0,0 +1,272 @@ +/* + * @brief Error code returned by Boot ROM drivers/library functions + * + * This file contains unified error codes to be used across driver, + * middleware, applications, hal and demo software. + * + * + * @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_ERROR_H__ +#define __LPC_ERROR_H__ + +/** 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 Success */ + /**\b 0xFFFFFFFF*/ ERR_FAILED = -1, /**< enum value returned on general failure */ + /**\b 0xFFFFFFFE*/ ERR_TIME_OUT = -2, /**< enum value returned on general timeout */ + /**\b 0xFFFFFFFD*/ ERR_BUSY = -3, /**< enum value returned when resource is busy */ + + /* ISP related errors */ + ERR_ISP_BASE = 0x00000000, + /*0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1, + /*0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /* Source address not on word boundary */ + /*0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /* Destination address not on word or 256 byte boundary */ + /*0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED, + /*0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED, + /*0x00000006*/ ERR_ISP_COUNT_ERROR, /* Byte count is not multiple of 4 or is not a permitted value */ + /*0x00000007*/ ERR_ISP_INVALID_SECTOR, + /*0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK, + /*0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION, + /*0x0000000A*/ ERR_ISP_COMPARE_ERROR, + /*0x0000000B*/ ERR_ISP_BUSY, /* Flash programming hardware interface is busy */ + /*0x0000000C*/ ERR_ISP_PARAM_ERROR, /* Insufficient number of parameters */ + /*0x0000000D*/ ERR_ISP_ADDR_ERROR, /* Address not on word boundary */ + /*0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED, + /*0x0000000F*/ ERR_ISP_CMD_LOCKED, /* Command is locked */ + /*0x00000010*/ ERR_ISP_INVALID_CODE, /* Unlock code is invalid */ + /*0x00000011*/ ERR_ISP_INVALID_BAUD_RATE, + /*0x00000012*/ ERR_ISP_INVALID_STOP_BIT, + /*0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED, + /*0x00000014*/ ERR_ISP_INVALID_FLASH_UNIT, + /*0x00000015*/ ERR_ISP_USER_CODE_CHECKSUM, + /*0x00000016*/ ERR_ISP_SETTING_ACTIVE_PARTITION, + /*0x00000017*/ ERR_ISP_IRC_NO_POWER, + /*0x00000018*/ ERR_ISP_FLASH_NO_POWER, + /*0x00000019*/ ERR_ISP_EEPROM_NO_POWER, + /*0x0000001A*/ ERR_ISP_EEPROM_NO_CLOCK, + /*0x0000001B*/ ERR_ISP_FLASH_NO_CLOCK, + /*0x0000001C*/ ERR_ISP_REINVOKE_ISP_CONFIG, + + /* ROM API related errors */ + ERR_API_BASE = 0x00010000, + /**\b 0x00010001*/ ERR_API_INVALID_PARAMS = ERR_API_BASE + 1, /**< Invalid parameters*/ + /**\b 0x00010002*/ ERR_API_INVALID_PARAM1, /**< PARAM1 is invalid */ + /**\b 0x00010003*/ ERR_API_INVALID_PARAM2, /**< PARAM2 is invalid */ + /**\b 0x00010004*/ ERR_API_INVALID_PARAM3, /**< PARAM3 is invalid */ + /**\b 0x00010005*/ ERR_API_MOD_INIT, /**< API is called before module init */ + + /* SPIFI API related errors */ + ERR_SPIFI_BASE = 0x00020000, + /*0x00020001*/ ERR_SPIFI_DEVICE_ERROR =ERR_SPIFI_BASE+1, + /*0x00020002*/ ERR_SPIFI_INTERNAL_ERROR, + /*0x00020003*/ ERR_SPIFI_TIMEOUT, + /*0x00020004*/ ERR_SPIFI_OPERAND_ERROR, + /*0x00020005*/ ERR_SPIFI_STATUS_PROBLEM, + /*0x00020006*/ ERR_SPIFI_UNKNOWN_EXT, + /*0x00020007*/ ERR_SPIFI_UNKNOWN_ID, + /*0x00020008*/ ERR_SPIFI_UNKNOWN_TYPE, + /*0x00020009*/ ERR_SPIFI_UNKNOWN_MFG, + /*0x0002000A*/ ERR_SPIFI_NO_DEVICE, + /*0x0002000B*/ ERR_SPIFI_ERASE_NEEDED, + + SEC_AES_NO_ERROR=0, + /* Security API related errors */ + ERR_SEC_AES_BASE = 0x00030000, + /*0x00030001*/ ERR_SEC_AES_WRONG_CMD=ERR_SEC_AES_BASE+1, + /*0x00030002*/ ERR_SEC_AES_NOT_SUPPORTED, + /*0x00030003*/ ERR_SEC_AES_KEY_ALREADY_PROGRAMMED, + /*0x00030004*/ ERR_SEC_AES_DMA_CHANNEL_CFG, + /*0x00030005*/ ERR_SEC_AES_DMA_MUX_CFG, + /*0x00030006*/ SEC_AES_DMA_BUSY, + + /* USB device stack related errors */ + ERR_USBD_BASE = 0x00040000, + /**\b 0x00040001*/ ERR_USBD_INVALID_REQ = ERR_USBD_BASE + 1, /**< invalid request */ + /**\b 0x00040002*/ ERR_USBD_UNHANDLED, /**< Callback did not process the event */ + /**\b 0x00040003*/ ERR_USBD_STALL, /**< Stall the endpoint on which the call back is called */ + /**\b 0x00040004*/ ERR_USBD_SEND_ZLP, /**< Send ZLP packet on the endpoint on which the call back is called */ + /**\b 0x00040005*/ ERR_USBD_SEND_DATA, /**< Send data packet on the endpoint on which the call back is called */ + /**\b 0x00040006*/ ERR_USBD_BAD_DESC, /**< Bad descriptor*/ + /**\b 0x00040007*/ ERR_USBD_BAD_CFG_DESC,/**< Bad config descriptor*/ + /**\b 0x00040008*/ ERR_USBD_BAD_INTF_DESC,/**< Bad interface descriptor*/ + /**\b 0x00040009*/ ERR_USBD_BAD_EP_DESC,/**< Bad endpoint descriptor*/ + /**\b 0x0004000a*/ ERR_USBD_BAD_MEM_BUF, /**< Bad alignment of buffer passed. */ + /**\b 0x0004000b*/ ERR_USBD_TOO_MANY_CLASS_HDLR, /**< Too many class handlers. */ + + /* CGU related errors */ + ERR_CGU_BASE = 0x00050000, + /*0x00050001*/ ERR_CGU_NOT_IMPL=ERR_CGU_BASE+1, + /*0x00050002*/ ERR_CGU_INVALID_PARAM, + /*0x00050003*/ ERR_CGU_INVALID_SLICE, + /*0x00050004*/ ERR_CGU_OUTPUT_GEN, + /*0x00050005*/ ERR_CGU_DIV_SRC, + /*0x00050006*/ ERR_CGU_DIV_VAL, + /*0x00050007*/ ERR_CGU_SRC, + + /* I2C related errors */ + ERR_I2C_BASE = 0x00060000, + /*0x00060000*/ ERR_I2C_BUSY = ERR_I2C_BASE, + /*0x00060001*/ ERR_I2C_NAK, + /*0x00060002*/ ERR_I2C_BUFFER_OVERFLOW, + /*0x00060003*/ ERR_I2C_BYTE_COUNT_ERR, + /*0x00060004*/ ERR_I2C_LOSS_OF_ARBRITRATION, + /*0x00060005*/ ERR_I2C_SLAVE_NOT_ADDRESSED, + /*0x00060006*/ ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT, + /*0x00060007*/ ERR_I2C_GENERAL_FAILURE, + /*0x00060008*/ ERR_I2C_REGS_SET_TO_DEFAULT, + /*0x00060009*/ ERR_I2C_TIMEOUT, + /*0x0006000A*/ ERR_I2C_BUFFER_UNDERFLOW, + /*0x0006000B*/ ERR_I2C_PARAM, + + /* OTP related errors */ + ERR_OTP_BASE = 0x00070000, + /*0x00070001*/ ERR_OTP_WR_ENABLE_INVALID = ERR_OTP_BASE+1, + /*0x00070002*/ ERR_OTP_SOME_BITS_ALREADY_PROGRAMMED, + /*0x00070003*/ ERR_OTP_ALL_DATA_OR_MASK_ZERO, + /*0x00070004*/ ERR_OTP_WRITE_ACCESS_LOCKED, + /*0x00070005*/ ERR_OTP_READ_DATA_MISMATCH, + /*0x00070006*/ ERR_OTP_USB_ID_ENABLED, + /*0x00070007*/ ERR_OTP_ETH_MAC_ENABLED, + /*0x00070008*/ ERR_OTP_AES_KEYS_ENABLED, + /*0x00070009*/ ERR_OTP_ILLEGAL_BANK, + + /* UART related errors */ + ERR_UART_BASE = 0x00080000, + /*0x00080001*/ ERR_UART_RXD_BUSY = ERR_UART_BASE+1, //UART rxd is busy + /*0x00080002*/ ERR_UART_TXD_BUSY, //UART txd is busy + /*0x00080003*/ ERR_UART_OVERRUN_FRAME_PARITY_NOISE, //overrun err, frame err, parity err, RxNoise err + /*0x00080004*/ ERR_UART_UNDERRUN, //underrun err + /*0x00080005*/ ERR_UART_PARAM, //parameter is error + /*0x00080006*/ ERR_UART_BAUDRATE, //baudrate setting is error + + /* CAN related errors */ + ERR_CAN_BASE = 0x00090000, + /*0x00090001*/ ERR_CAN_BAD_MEM_BUF = ERR_CAN_BASE+1, + /*0x00090002*/ ERR_CAN_INIT_FAIL, + /*0x00090003*/ ERR_CANOPEN_INIT_FAIL, + + /* SPIFI Lite API related errors */ + ERR_SPIFI_LITE_BASE = 0x000A0000, + /*0x000A0001*/ ERR_SPIFI_LITE_INVALID_ARGUMENTS = ERR_SPIFI_LITE_BASE+1, + /*0x000A0002*/ ERR_SPIFI_LITE_BUSY, + /*0x000A0003*/ ERR_SPIFI_LITE_MEMORY_MODE_ON, + /*0x000A0004*/ ERR_SPIFI_LITE_MEMORY_MODE_OFF, + /*0x000A0005*/ ERR_SPIFI_LITE_IN_DMA, + /*0x000A0006*/ ERR_SPIFI_LITE_NOT_IN_DMA, + /*0x000A0100*/ PENDING_SPIFI_LITE, + + /* CLK related errors */ + ERR_CLK_BASE = 0x000B0000, + /*0x000B0001*/ ERR_CLK_NOT_IMPL=ERR_CLK_BASE+1, + /*0x000B0002*/ ERR_CLK_INVALID_PARAM, + /*0x000B0003*/ ERR_CLK_INVALID_SLICE, + /*0x000B0004*/ ERR_CLK_OUTPUT_GEN, + /*0x000B0005*/ ERR_CLK_DIV_SRC, + /*0x000B0006*/ ERR_CLK_DIV_VAL, + /*0x000B0007*/ ERR_CLK_SRC, + /*0x000B0008*/ ERR_CLK_PLL_FIN_TOO_SMALL, + /*0x000B0009*/ ERR_CLK_PLL_FIN_TOO_LARGE, + /*0x000B000A*/ ERR_CLK_PLL_FOUT_TOO_SMALL, + /*0x000B000B*/ ERR_CLK_PLL_FOUT_TOO_LARGE, + /*0x000B000C*/ ERR_CLK_PLL_NO_SOLUTION, + /*0x000B000D*/ ERR_CLK_PLL_MIN_PCT, + /*0x000B000E*/ ERR_CLK_PLL_MAX_PCT, + /*0x000B000F*/ ERR_CLK_OSC_FREQ, + /*0x000B0010*/ ERR_CLK_CFG, + /*0x000B0011*/ ERR_CLK_TIMEOUT, + /*0x000B0012*/ ERR_CLK_BASE_OFF, + /*0x000B0013*/ ERR_CLK_OFF_DEADLOCK, + + /*Power API*/ + ERR_PWR_BASE = 0x000C0000, + /*0x000C0001*/ PWR_ERROR_ILLEGAL_MODE=ERR_PWR_BASE+1, + /*0x000C0002*/ PWR_ERROR_CLOCK_FREQ_TOO_HIGH, + /*0x000C0003*/ PWR_ERROR_INVALID_STATE, + /*0x000C0004*/ PWR_ERROR_INVALID_CFG, + /*0x000C0005*/ PWR_ERROR_PVT_DETECT, + + /* DMA related errors */ + ERR_DMA_BASE = 0x000D0000, + /*0x000D0001*/ ERR_DMA_ERROR_INT=ERR_DMA_BASE+1, + /*0x000D0002*/ ERR_DMA_CHANNEL_NUMBER, + /*0x000D0003*/ ERR_DMA_CHANNEL_DISABLED, + /*0x000D0004*/ ERR_DMA_BUSY, + /*0x000D0005*/ ERR_DMA_NOT_ALIGNMENT, + /*0x000D0006*/ ERR_DMA_PING_PONG_EN, + /*0x000D0007*/ ERR_DMA_CHANNEL_VALID_PENDING, + /*0x000D0008*/ ERR_DMA_PARAM, + /*0x000D0009*/ ERR_DMA_QUEUE_EMPTY, + /*0x000D000A*/ ERR_DMA_GENERAL, + + /* SPI related errors */ + ERR_SPI_BASE = 0x000E0000, + /*0x000E0000*/ ERR_SPI_BUSY=ERR_SPI_BASE, + /*0x000E0001*/ ERR_SPI_RXOVERRUN, + /*0x000E0002*/ ERR_SPI_TXUNDERRUN, + /*0x000E0003*/ ERR_SPI_SELNASSERT, + /*0x000E0004*/ ERR_SPI_SELNDEASSERT, + /*0x000E0005*/ ERR_SPI_CLKSTALL, + /*0x000E0006*/ ERR_SPI_PARAM, + /*0x000E0007*/ ERR_SPI_INVALID_LENGTH, + + /* ADC related errors */ + ERR_ADC_BASE = 0x000F0000, + /*0x000F0001*/ ERR_ADC_OVERRUN=ERR_ADC_BASE+1, + /*0x000F0002*/ ERR_ADC_INVALID_CHANNEL, + /*0x000F0003*/ ERR_ADC_INVALID_SEQUENCE, + /*0x000F0004*/ ERR_ADC_INVALID_SETUP, + /*0x000F0005*/ ERR_ADC_PARAM, + /*0x000F0006*/ ERR_ADC_INVALID_LENGTH, + /*0x000F0007*/ ERR_ADC_NO_POWER, + + /* Debugger Mailbox related errors */ + ERR_DM_BASE = 0x00100000, + /*0x00100001*/ ERR_DM_NOT_ENTERED=ERR_DM_BASE+1, + /*0x00100002*/ ERR_DM_UNKNOWN_CMD, + /*0x00100003*/ ERR_DM_COMM_FAIL + +} ErrorCode_t; + +#ifndef offsetof +#define offsetof(s, m) (int) &(((s *) 0)->m) +#endif + +#define COMPILE_TIME_ASSERT(pred) switch (0) { \ + case 0: \ + case pred:; } + +#endif /* __LPC_ERROR_H__ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.c new file mode 100644 index 0000000000000000000000000000000000000000..88125dda5e571512395d22bfc8d3b306a46f6551 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.c @@ -0,0 +1,97 @@ +/* + * @brief FPU init code + * + * @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. + */ + +#if defined(CORE_M4) + +#include "sys_config.h" +#include "cmsis.h" +#include "stdint.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define LPC_CPACR 0xE000ED88 + +#define SCB_MVFR0 0xE000EF40 +#define SCB_MVFR0_RESET 0x10110021 + +#define SCB_MVFR1 0xE000EF44 +#define SCB_MVFR1_RESET 0x11000011 + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Early initialization of the FPU */ +void fpuInit(void) +{ +#if __FPU_PRESENT != 0 + // from arm trm manual: + // ; CPACR is located at address 0xE000ED88 + // LDR.W R0, =0xE000ED88 + // ; Read CPACR + // LDR R1, [R0] + // ; Set bits 20-23 to enable CP10 and CP11 coprocessors + // ORR R1, R1, #(0xF << 20) + // ; Write back the modified value to the CPACR + // STR R1, [R0] + + volatile uint32_t *regCpacr = (uint32_t *) LPC_CPACR; + volatile uint32_t *regMvfr0 = (uint32_t *) SCB_MVFR0; + volatile uint32_t *regMvfr1 = (uint32_t *) SCB_MVFR1; + volatile uint32_t Cpacr; + volatile uint32_t Mvfr0; + volatile uint32_t Mvfr1; + char vfpPresent = 0; + + Mvfr0 = *regMvfr0; + Mvfr1 = *regMvfr1; + + vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1)); + + if (vfpPresent) { + Cpacr = *regCpacr; + Cpacr |= (0xF << 20); + *regCpacr = Cpacr; // enable CP10 and CP11 for full access + } +#endif /* __FPU_PRESENT != 0 */ +} + +#endif /* defined(CORE_M4 */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.h new file mode 100644 index 0000000000000000000000000000000000000000..86e71c89875a132b39045b542b918076bd15afc4 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/fpu_init.h @@ -0,0 +1,52 @@ +/* + * @brief FPU init code + * + * @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 __FPU_INIT_H_ +#define __FPU_INIT_H_ + +/** + * @defgroup CHIP_FPU_CMX CHIP: FPU initialization + * @ingroup CHIP_Common + * Cortex FPU initialization + * @{ + */ + +/** + * @brief Early initialization of the FPU + * @return Nothing + */ +void fpuInit(void); + +/** + * @} + */ + +#endif /* __FPU_INIT_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.c new file mode 100644 index 0000000000000000000000000000000000000000..76f72a2f59b63cc14ac493f9e00ab4529ef6f6d2 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.c @@ -0,0 +1,175 @@ +/* + * @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[4]; + + 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[4]; + + 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[4]; + + 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[4]; + + 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() +{ + uint32_t command[5], result[4]; + + command[0] = IAP_REPID_CMD; + iap_entry(command, result); + + return result[1]; +} + +/* Read boot code version number */ +uint8_t Chip_IAP_ReadBootCode() +{ + uint32_t command[5], result[4]; + + command[0] = IAP_READ_BOOT_CODE_CMD; + iap_entry(command, result); + + return result[0]; +} + +/* IAP compare */ +uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp) +{ + uint32_t command[5], result[4]; + + 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() +{ + uint32_t command[5], result[4]; + + command[0] = IAP_REINVOKE_ISP_CMD; + iap_entry(command, result); + + return result[0]; +} + +/* Read the unique ID */ +uint32_t Chip_IAP_ReadUID() +{ + uint32_t command[5], result[4]; + + command[0] = IAP_READ_UID_CMD; + iap_entry(command, result); + + return result[1]; +} + +/* Erase page */ +uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage) +{ + uint32_t command[5], result[4]; + + command[0] = IAP_ERASE_PAGE_CMD; + command[1] = strPage; + command[2] = endPage; + command[3] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.h new file mode 100644 index 0000000000000000000000000000000000000000..a90e87c9b7ba6a457e8645de4cc7ec8b7abe37b3 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/iap.h @@ -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[5], unsigned int[4]); + +/** + * @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 flash 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 + */ +uint8_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(void); + +/** + * @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_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/lpc_types.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/lpc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..14c7b605009928b91dba96420337f08b162e2513 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/lpc_types.h @@ -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 +#include + +/** @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: + * = (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_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/packing.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/packing.h new file mode 100644 index 0000000000000000000000000000000000000000..c2b9631bb3286a38ae113a5e868908e3a41a1404 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/packing.h @@ -0,0 +1,39 @@ +/* + * @brief Packing macros + * + * @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 __PACKING_H_ +#define __PACKING_H_ + +#define PRE_PACK /* Nothing */ +#define POST_PACK /* Nothing */ +#define ALIGNED(n) /* Nothing */ + +#endif /* __PACKING_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..47a0c34f95fc7558a63b3d297d9e62ac0f048325 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.c @@ -0,0 +1,167 @@ +/* + * @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 +#include "ring_buffer.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define RB_INDH(rb) ((rb)->head & ((rb)->count - 1)) +#define RB_INDT(rb) ((rb)->tail & ((rb)->count - 1)) + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize ring buffer */ +int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count) +{ + RingBuff->data = buffer; + RingBuff->count = count; + RingBuff->itemSz = itemSize; + RingBuff->head = RingBuff->tail = 0; + + return 1; +} + +/* Insert a single item into Ring Buffer */ +int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data) +{ + uint8_t *ptr = RingBuff->data; + + /* We cannot insert when queue is full */ + if (RingBuffer_IsFull(RingBuff)) + return 0; + + ptr += RB_INDH(RingBuff) * RingBuff->itemSz; + memcpy(ptr, data, RingBuff->itemSz); + RingBuff->head++; + + return 1; +} + +/* Insert multiple items into Ring Buffer */ +int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num) +{ + uint8_t *ptr = RingBuff->data; + int cnt1, cnt2; + + /* We cannot insert when queue is full */ + if (RingBuffer_IsFull(RingBuff)) + return 0; + + /* Calculate the segment lengths */ + cnt1 = cnt2 = RingBuffer_GetFree(RingBuff); + if (RB_INDH(RingBuff) + cnt1 >= RingBuff->count) + cnt1 = RingBuff->count - RB_INDH(RingBuff); + cnt2 -= cnt1; + + cnt1 = MIN(cnt1, num); + num -= cnt1; + + cnt2 = MIN(cnt2, num); + num -= cnt2; + + /* Write segment 1 */ + ptr += RB_INDH(RingBuff) * RingBuff->itemSz; + memcpy(ptr, data, cnt1 * RingBuff->itemSz); + RingBuff->head += cnt1; + + /* Write segment 2 */ + ptr = (uint8_t *) RingBuff->data + RB_INDH(RingBuff) * RingBuff->itemSz; + data = (const uint8_t *) data + cnt1 * RingBuff->itemSz; + memcpy(ptr, data, cnt2 * RingBuff->itemSz); + RingBuff->head += cnt2; + + return cnt1 + cnt2; +} + +/* Pop single item from Ring Buffer */ +int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data) +{ + uint8_t *ptr = RingBuff->data; + + /* We cannot pop when queue is empty */ + if (RingBuffer_IsEmpty(RingBuff)) + return 0; + + ptr += RB_INDT(RingBuff) * RingBuff->itemSz; + memcpy(data, ptr, RingBuff->itemSz); + RingBuff->tail++; + + return 1; +} + +/* Pop multiple items from Ring buffer */ +int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num) +{ + uint8_t *ptr = RingBuff->data; + int cnt1, cnt2; + + /* We cannot insert when queue is empty */ + if (RingBuffer_IsEmpty(RingBuff)) + return 0; + + /* Calculate the segment lengths */ + cnt1 = cnt2 = RingBuffer_GetCount(RingBuff); + if (RB_INDT(RingBuff) + cnt1 >= RingBuff->count) + cnt1 = RingBuff->count - RB_INDT(RingBuff); + cnt2 -= cnt1; + + cnt1 = MIN(cnt1, num); + num -= cnt1; + + cnt2 = MIN(cnt2, num); + num -= cnt2; + + /* Write segment 1 */ + ptr += RB_INDT(RingBuff) * RingBuff->itemSz; + memcpy(data, ptr, cnt1 * RingBuff->itemSz); + RingBuff->tail += cnt1; + + /* Write segment 2 */ + ptr = (uint8_t *) RingBuff->data + RB_INDT(RingBuff) * RingBuff->itemSz; + data = (uint8_t *) data + cnt1 * RingBuff->itemSz; + memcpy(data, ptr, cnt2 * RingBuff->itemSz); + RingBuff->tail += cnt2; + + return cnt1 + cnt2; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..8c205fd3a8a00265dd4dc328c606289c2fcfcb79 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/ring_buffer.h @@ -0,0 +1,188 @@ +/* + * @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 "lpc_types.h" + +/** @defgroup Ring_Buffer CHIP: Simple ring buffer implementation + * @ingroup CHIP_Common + * @{ + */ + +/** + * @brief Ring buffer structure + */ +typedef struct { + void *data; + int count; + int itemSz; + uint32_t head; + uint32_t tail; +} RINGBUFF_T; + +/** + * @def RB_VHEAD(rb) + * volatile typecasted head index + */ +#define RB_VHEAD(rb) (*(volatile uint32_t *) &(rb)->head) + +/** + * @def RB_VTAIL(rb) + * volatile typecasted tail index + */ +#define RB_VTAIL(rb) (*(volatile uint32_t *) &(rb)->tail) + +/** + * @brief Initialize ring buffer + * @param RingBuff : Pointer to ring buffer to initialize + * @param buffer : Pointer to buffer to associate with RingBuff + * @param itemSize : Size of each buffer item size + * @param count : Size of ring buffer + * @note Memory pointed by @a buffer must have correct alignment of + * @a itemSize, and @a count must be a power of 2 and must at + * least be 2 or greater. + * @return Nothing + */ +int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count); + +/** + * @brief Resets the ring buffer to empty + * @param RingBuff : Pointer to ring buffer + * @return Nothing + */ +STATIC INLINE void RingBuffer_Flush(RINGBUFF_T *RingBuff) +{ + RingBuff->head = RingBuff->tail = 0; +} + +/** + * @brief Return size the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Size of the ring buffer in bytes + */ +STATIC INLINE int RingBuffer_GetSize(RINGBUFF_T *RingBuff) +{ + return RingBuff->count; +} + +/** + * @brief Return number of items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Number of items in the ring buffer + */ +STATIC INLINE int RingBuffer_GetCount(RINGBUFF_T *RingBuff) +{ + return RB_VHEAD(RingBuff) - RB_VTAIL(RingBuff); +} + +/** + * @brief Return number of free items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Number of free items in the ring buffer + */ +STATIC INLINE int RingBuffer_GetFree(RINGBUFF_T *RingBuff) +{ + return RingBuff->count - RingBuffer_GetCount(RingBuff); +} + +/** + * @brief Return number of items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return 1 if the ring buffer is full, otherwise 0 + */ +STATIC INLINE int RingBuffer_IsFull(RINGBUFF_T *RingBuff) +{ + return (RingBuffer_GetCount(RingBuff) >= RingBuff->count); +} + +/** + * @brief Return empty status of ring buffer + * @param RingBuff : Pointer to ring buffer + * @return 1 if the ring buffer is empty, otherwise 0 + */ +STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff) +{ + return RB_VHEAD(RingBuff) == RB_VTAIL(RingBuff); +} + +/** + * @brief Insert a single item into ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : pointer to item + * @return 1 when successfully inserted, + * 0 on error (Buffer not initialized using + * RingBuffer_Init() or attempted to insert + * when buffer is full) + */ +int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data); + +/** + * @brief Insert an array of items into ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to first element of the item array + * @param num : Number of items in the array + * @return number of items successfully inserted, + * 0 on error (Buffer not initialized using + * RingBuffer_Init() or attempted to insert + * when buffer is full) + */ +int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num); + +/** + * @brief Pop an item from the ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to memory where popped item be stored + * @return 1 when item popped successfuly onto @a data, + * 0 When error (Buffer not initialized using + * RingBuffer_Init() or attempted to pop item when + * the buffer is empty) + */ +int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data); + +/** + * @brief Pop an array of items from the ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to memory where popped items be stored + * @param num : Max number of items array @a data can hold + * @return Number of items popped onto @a data, + * 0 on error (Buffer not initialized using RingBuffer_Init() + * or attempted to pop when the buffer is empty) + */ +int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num); + + +/** + * @} + */ + +#endif /* __RING_BUFFER_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.c b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.c new file mode 100644 index 0000000000000000000000000000000000000000..c998261489b8756857733552639b8c6d3b53e387 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.c @@ -0,0 +1,202 @@ +/* + * @brief RTC tick to (a more) Universal Time + * Adds conversion functions to use an RTC that only provides a + * seconds capability to provide "struct tm" support. + * + * @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 "rtc_ut.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define SECSPERMIN (60) +#define MINSPERHOUR (60) +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define HOURSPERDAY (24) +#define SECSPERDAY (SECSPERMIN * MINSPERHOUR * HOURSPERDAY) +#define DAYSPERWEEK (7) +#define MONETHSPERYEAR (12) +#define DAYSPERYEAR (365) +#define DAYSPERLEAPYEAR (366) + +/* Days per month, LY is special */ +static uint8_t daysPerMonth[2][MONETHSPERYEAR] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Normal year */ + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Leap year */ +}; + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Converts the number of days offset from the start year to real year + data accounting for leap years */ +static void GetDMLY(int dayOff, struct tm *pTime) +{ + bool YearFound = false; + int daysYear = dayOff; + int leapYear, curLeapYear, year = TM_YEAR_BASE, monthYear = 0; + bool MonthFound = false; + + /* Leap year check for less than 1 year time */ + if ((year % 4) == 0) { + curLeapYear = 1; + } + else { + curLeapYear = 0; + } + + /* Determine offset of years from days offset */ + while (YearFound == false) { + if ((year % 4) == 0) { + /* Leap year, 366 days */ + daysYear = DAYSPERLEAPYEAR; + leapYear = 1; + } + else { + /* Leap year, 365 days */ + daysYear = DAYSPERYEAR; + leapYear = 0; + } + + if (dayOff > daysYear) { + dayOff -= daysYear; + year++; + } + else { + YearFound = true; + curLeapYear = leapYear; /* In a leap year */ + } + } + + /* Save relative year and day into year */ + pTime->tm_year = year - TM_YEAR_BASE; /* Base year relative */ + pTime->tm_yday = dayOff;/* 0 relative */ + + /* Determine offset of months from days offset */ + while (MonthFound == false) { + if ((dayOff + 1) > daysPerMonth[curLeapYear][monthYear]) { + /* Next month */ + dayOff -= daysPerMonth[curLeapYear][monthYear]; + monthYear++; + } + else { + /* Month found */ + MonthFound = true; + } + } + + pTime->tm_mday = dayOff + 1;/* 1 relative */ + pTime->tm_mon = monthYear; /* 0 relative */ +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Converts an RTC tick time to Universal time */ +void ConvertRtcTime(uint32_t rtcTick, struct tm *pTime) +{ + int daySeconds, dayNum; + + /* Get day offset and seconds since start */ + dayNum = (int) (rtcTick / SECSPERDAY); + daySeconds = (int) (rtcTick % SECSPERDAY); + + /* Fill in secs, min, hours */ + pTime->tm_sec = daySeconds % 60; + pTime->tm_hour = daySeconds / SECSPERHOUR; + pTime->tm_min = (daySeconds - (pTime->tm_hour * SECSPERHOUR)) / SECSPERMIN; + + /* Weekday, 0 = Sunday, 6 = Saturday */ + pTime->tm_wday = (dayNum + TM_DAYOFWEEK) % DAYSPERWEEK; + + /* Get year, month, day of month, and day of year */ + GetDMLY(dayNum, pTime); + + /* Not supported in this driver */ + pTime->tm_isdst = 0; +} + +/* Converts a Universal time to RTC tick time */ +void ConvertTimeRtc(struct tm *pTime, uint32_t *rtcTick) +{ + int leapYear, year = pTime->tm_year + TM_YEAR_BASE; + uint32_t dayOff, monthOff, monthCur, rtcTicks = 0; + + /* Leap year check for less than 1 year time */ + if ((year % 4) == 0) { + leapYear = 1; + } + else { + leapYear = 0; + } + + /* Add days for each year and leap year */ + while (year > TM_YEAR_BASE) { + if ((year % 4) == 0) { + /* Leap year, 366 days */ + rtcTicks += DAYSPERLEAPYEAR * SECSPERDAY; + leapYear = 1; + } + else { + /* Leap year, 365 days */ + rtcTicks += DAYSPERYEAR * SECSPERDAY; + leapYear = 0; + } + + year--; + } + + /* Day and month are 0 relative offsets since day and month + start at 1 */ + dayOff = (uint32_t) pTime->tm_mday - 1; + monthOff = (uint32_t) pTime->tm_mon; + + /* Add in seconds for passed months */ + for (monthCur = 0; monthCur < monthOff; monthCur++) { + rtcTicks += (uint32_t) (daysPerMonth[leapYear][monthCur] * SECSPERDAY); + } + + /* Add in seconds for day offset into the current month */ + rtcTicks += (dayOff * SECSPERDAY); + + /* Add in seconds for hours, minutes, and seconds */ + rtcTicks += (uint32_t) (pTime->tm_hour * SECSPERHOUR); + rtcTicks += (uint32_t) (pTime->tm_min * SECSPERMIN); + rtcTicks += (uint32_t) pTime->tm_sec; + + *rtcTick = rtcTicks; +} diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.h new file mode 100644 index 0000000000000000000000000000000000000000..c88ca598ae70625cc26f1b4bccc80d862bb225b6 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/rtc_ut.h @@ -0,0 +1,84 @@ +/* + * @brief RTC tick to (a more) Universal Time + * Adds conversion functions to use an RTC that only provides a + * seconds capability to provide "struct tm" support. + * + * @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 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 __RTC_UT_H_ +#define __RTC_UT_H_ + +#include "chip.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup RTC_UT CHIP: RTC tick to (a more) Universal Time conversion functions + * @ingroup CHIP_Common + * This driver converts between a RTC 1-second tick value and + * a Universal time format in a structure of type 'struct tm'. + * @{ + */ + +/* Starting year and starting day of week for the driver */ +#define TM_YEAR_BASE (1900) +#define TM_DAYOFWEEK (1) + +/** + * @brief Converts a RTC tick time to Universal time + * @param rtcTick : Current RTC time value + * @param pTime : Pointer to time structure to fill + * @return Nothing + * @note When setting time, the 'tm_wday', 'tm_yday', and 'tm_isdst' + * fields are not used. + */ +void ConvertRtcTime(uint32_t rtcTick, struct tm *pTime); + +/** + * @brief Converts a Universal time to RTC tick time + * @param pTime : Pointer to time structure to use + * @param rtcTick : Pointer to RTC time value to fill + * @return Nothing + * @note When converting time, the 'tm_isdst' field is not + * populated by the conversion function. + */ +void ConvertTimeRtc(struct tm *pTime, uint32_t *rtcTick); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RTC_UT_H_ */ diff --git a/bsp/lpc5410x/Libraries/lpc_chip/chip_common/stopwatch.h b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/stopwatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c298735fa2a84d2603ac18cb56837db92106d953 --- /dev/null +++ b/bsp/lpc5410x/Libraries/lpc_chip/chip_common/stopwatch.h @@ -0,0 +1,137 @@ +/* + * @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 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_ */ diff --git a/bsp/lpc5410x/SConscript b/bsp/lpc5410x/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..381b1612c717a6aff6ebf99434da07ca16fce99b --- /dev/null +++ b/bsp/lpc5410x/SConscript @@ -0,0 +1,12 @@ +from building import * + +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') diff --git a/bsp/lpc5410x/SConstruct b/bsp/lpc5410x/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..fb728723bc79c34a28627a862ea05693250906e2 --- /dev/null +++ b/bsp/lpc5410x/SConstruct @@ -0,0 +1,30 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread-%s.%s' % (rtconfig.BOARD_NAME, rtconfig.TARGET_EXT) + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/lpc5410x/applications/SConscript b/bsp/lpc5410x/applications/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..01eb940dfb35f92c503a78b0b49a4354590f9f3a --- /dev/null +++ b/bsp/lpc5410x/applications/SConscript @@ -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') diff --git a/bsp/lpc5410x/applications/application.c b/bsp/lpc5410x/applications/application.c new file mode 100644 index 0000000000000000000000000000000000000000..726687fd74e6e7f31ff492afeabb1d14ec3f30a2 --- /dev/null +++ b/bsp/lpc5410x/applications/application.c @@ -0,0 +1,45 @@ +/* + * 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 + */ + +#include +#ifdef RT_USING_FINSH +#include +#include +#endif + + +extern int demo_init(void); + +void rt_init_thread_entry(void* parameter) +{ + /* initialization finsh shell Component */ + finsh_system_init(); + + demo_init(); + +} + +int rt_application_init() +{ + rt_thread_t tid; + + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX/3, 20); + if (tid != RT_NULL) + rt_thread_startup(tid); + + + return 0; +} diff --git a/bsp/lpc5410x/applications/board.c b/bsp/lpc5410x/applications/board.c new file mode 100644 index 0000000000000000000000000000000000000000..d6be4bd50c94674da98dbb89ee1e6f8a7e5f1b50 --- /dev/null +++ b/bsp/lpc5410x/applications/board.c @@ -0,0 +1,105 @@ +/* + * 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 + * 2010-02-04 Magicoe ported to LPC17xx + * 2010-05-02 Aozima update CMSIS to 130 + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#ifdef RT_USING_COMPONENTS_INIT +#include +#endif + + + +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + + + + +/** + * This function will initial LPC54xx board. + */ +void rt_hw_board_init() +{ + /* NVIC Configuration */ +#define NVIC_VTOR_MASK 0x3FFFFF80 +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x00000000 */ + SCB->VTOR = (0x00000000 & NVIC_VTOR_MASK); +#endif + SystemCoreClockUpdate(); + /* init systick 1 systick = 1/(100M / 100) 100¸ösystick = 1s*/ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND - 1); + /* set pend exception priority */ + NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1); + + /*init uart device*/ + rt_hw_uart_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); + +#if LPC_EXT_SDRAM == 1 + lpc_sdram_hw_init(); + mpu_init(); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + /* initialization board with RT-Thread Components */ + rt_components_board_init(); +#endif +} + + +/* initialization for system heap */ +int rt_hw_board_heap_init(void) +{ +#ifdef RT_USING_HEAP +#if LPC_EXT_SDRAM +#include "drv_sram.h" + rt_system_heap_init((void *)LPC_EXT_SDRAM_BEGIN, (void *)LPC_EXT_SDRAM_END); + sram_init(); +#else + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif +#endif + + return 0; +} + +void MemManage_Handler(void) +{ + extern void HardFault_Handler(void); + + rt_kprintf("Memory Fault!\n"); + HardFault_Handler(); +} diff --git a/bsp/lpc5410x/applications/board.h b/bsp/lpc5410x/applications/board.h new file mode 100644 index 0000000000000000000000000000000000000000..29c851413623b6e6868c87c47b27297a4bd0bbef --- /dev/null +++ b/bsp/lpc5410x/applications/board.h @@ -0,0 +1,69 @@ +/* + * 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 + * 2010-02-04 Magicoe add board.h to LPC176x bsp + * 2013-12-18 Bernard porting to LPC4088 bsp + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +//#include "LPC54xxx.h" +#include "chip.h" + + +#include + +/* disable SDRAM in default */ +#ifndef LPC_EXT_SDRAM +#define LPC_EXT_SDRAM 0 +#endif + +// + +// +#define LPC_EXT_SDRAM_BEGIN 0xA0000000 +// +#define LPC_EXT_SDRAM_END 0xA2000000 + +// +#define RT_USING_UART0 +// +//#define RT_USING_UART1 +// +#define RT_USING_UART2 +// +#define RT_CONSOLE_DEVICE_NAME "uart0" + +// + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define HEAP_BEGIN ((void *)&__bss_end) +#endif +#define HEAP_END (void*)(0x10000000 + 0x10000) + +void rt_hw_board_init(void); +int rt_hw_board_heap_init(void); + +#ifdef RT_USING_RTGUI +int rtgui_lcd_init(void); +int touch_calibration_init(void); +#endif + +#endif diff --git a/bsp/lpc5410x/applications/demo_thread.c b/bsp/lpc5410x/applications/demo_thread.c new file mode 100644 index 0000000000000000000000000000000000000000..f4bcea97738bf310f9bfe1c2e227f5bd69433fcb --- /dev/null +++ b/bsp/lpc5410x/applications/demo_thread.c @@ -0,0 +1,48 @@ +#include +#include "drv_led.h" +#include "drv_uart.h" + +static void thread1_entry(void* parameter) +{ + while(1) + { + Led_Control(0,1); + rt_thread_delay(RT_TICK_PER_SECOND); + Led_Control(0,0); + rt_thread_delay(RT_TICK_PER_SECOND); + } +} + +static void thread2_entry(void* parameter) +{ + while(1) + { + Led_Control(1,1); + rt_thread_delay(RT_TICK_PER_SECOND); + Led_Control(1,0); + rt_thread_delay(RT_TICK_PER_SECOND); + } +} + + +int demo_init(void) +{ + rt_thread_t thread1 = RT_NULL; + rt_thread_t thread2 = RT_NULL; + + + rt_led_hw_init(); + + + thread1 = rt_thread_create("t1",thread1_entry, RT_NULL,512,10,5); + if (thread1 != RT_NULL) + rt_thread_startup(thread1); + + thread2 = rt_thread_create("t2",thread2_entry, RT_NULL,512,10,5); + if (thread2 != RT_NULL) + rt_thread_startup(thread2); + + + return 0; + +} diff --git a/bsp/lpc5410x/applications/startup.c b/bsp/lpc5410x/applications/startup.c new file mode 100644 index 0000000000000000000000000000000000000000..02f5f0a6337d7d5c53dc582c08da67bf30397f5b --- /dev/null +++ b/bsp/lpc5410x/applications/startup.c @@ -0,0 +1,74 @@ +/* + * 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 +#include + +#include "board.h" + +extern int rt_application_init(void); + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* initialize board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* initialize tick */ + rt_system_tick_init(); + + /* initialize kernel object */ + rt_system_object_init(); + + /* initialize timer system */ + rt_system_timer_init(); + + /* initialize system heap */ + rt_system_heap_init(HEAP_BEGIN, HEAP_END); + + /* initialize scheduler system */ + rt_system_scheduler_init(); + + /* initialize application */ + rt_application_init(); + + /* initialize timer thread */ + rt_system_timer_thread_init(); + + /* initialize 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; +} diff --git a/bsp/lpc5410x/drivers/SConscript b/bsp/lpc5410x/drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..5c19ced1e99470edee082a236786c96c9e35999b --- /dev/null +++ b/bsp/lpc5410x/drivers/SConscript @@ -0,0 +1,17 @@ +#Import('RTT_ROOT') +#Import('rtconfig') +from building import * + +#cwd = os.path.join(str(Dir('#')),'drivers') +cwd = GetCurrentDir() +src = Glob('*.c') + +# remove no need file. +if GetDepend('RT_USING_LWIP') == False: + SrcRemove(src, 'drv_emac.c') + +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/lpc5410x/drivers/drv_led.c b/bsp/lpc5410x/drivers/drv_led.c new file mode 100644 index 0000000000000000000000000000000000000000..135562a98352b8e7f2d66b75bd56871982e527e2 --- /dev/null +++ b/bsp/lpc5410x/drivers/drv_led.c @@ -0,0 +1,210 @@ +#include +#include "board.h" + +#define LED_NUM 3 + +struct led_ctrl +{ + uint32_t num; + uint32_t port; +}; + +struct lpc_led +{ + /* inherit from rt_device */ + struct rt_device parent; + struct led_ctrl ctrl[LED_NUM]; +}; + +static struct lpc_led led; + +static rt_err_t rt_led_init(rt_device_t dev) +{ + /*led2 Blue:P0.31 ,led1 Green:P0.30 ,led0 Red:P0_29 P38,P32*/ + LPC_SYSCON->AHBCLKCTRLSET[0] = (1UL << 14); /* enable GPIO0 clock*/ + + LPC_SYSCON->PRESETCTRLSET[0] = (1UL << 14); /* Resets a GPIO0 peripheral */ + LPC_SYSCON->PRESETCTRLCLR[0] = (1UL << 14); + + /* set P0.31, P0.30, P0.29 output. */ + LPC_GPIO->DIR[0] |= 0x07UL << 29; + + /* turn off all the led */ + LPC_GPIO->SET[0] = 0x07UL << 29; + + led.ctrl[0].num = 29; + led.ctrl[0].port = 0; + led.ctrl[1].num = 30; + led.ctrl[1].port = 0; + led.ctrl[2].num = 31; + led.ctrl[2].port = 0; + + return RT_EOK; + +} + +static rt_err_t rt_led_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_led_close(rt_device_t dev) +{ + return RT_EOK; +} + + +static rt_size_t rt_led_read(rt_device_t dev, rt_off_t pos, void *buffer, + rt_size_t size) +{ + rt_ubase_t index = 0; + rt_ubase_t nr = size; + rt_uint8_t *value = buffer; + + RT_ASSERT(dev == &led.parent); + RT_ASSERT((pos + size) <= LED_NUM); + + for (index = 0; index < nr; index++) + { + //if ((LPC_GPIO->PIN[led.ctrl[pos + index].port]) & 1 << led.ctrl[pos + index].num) + if ((LPC_GPIO->B[0][led.ctrl[pos + index].num])) + { + *value = 0; + } + else + { + *value = 1; + } + value++; + } + return index; +} + + + +static rt_size_t rt_led_write(rt_device_t dev, rt_off_t pos, + const void *buffer, rt_size_t size) +{ + rt_ubase_t index = 0; + rt_ubase_t nw = size; + const rt_uint8_t *value = buffer; + + RT_ASSERT(dev == &led.parent); + RT_ASSERT((pos + size) <= LED_NUM); + for (index = 0; index < nw; index++) + { + if (*value > 0) + { + //LPC_GPIO->CLR[led.ctrl[pos + index].port] |= (1 << led.ctrl[pos + index].num); + LPC_GPIO->CLR[0] |= (1 << led.ctrl[pos + index].num); + } + else + { + //LPC_GPIO->SET[led.ctrl[pos + index].port] |= (1 << led.ctrl[pos + index].num); + LPC_GPIO->SET[0] |= (1 << led.ctrl[pos + index].num); + } + } + + return index; +} + + +static rt_err_t rt_led_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + return RT_EOK; +} + +int rt_led_hw_init(void) +{ + led.parent.type = RT_Device_Class_Char; + led.parent.rx_indicate = RT_NULL; + led.parent.tx_complete = RT_NULL; + led.parent.init = rt_led_init; + led.parent.open = rt_led_open; + led.parent.close = rt_led_close; + led.parent.read = rt_led_read; + led.parent.write = rt_led_write; + led.parent.control = rt_led_control; + led.parent.user_data = RT_NULL; + + /* register a character device */ + rt_device_register(&led.parent, "led", RT_DEVICE_FLAG_RDWR); + /* init led device */ + rt_led_init(&led.parent); + return 0; +} + + + +void Led_Control(rt_uint32_t Set_led, rt_uint32_t value) +{ + if ( Set_led == 0 ) + { + /* set led status */ + switch (value) + { + case 0: + /* Light off */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL; + break; + case 1: + /* Lights on */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL; + break; + default: + break; + } + } + + if ( Set_led == 1 ) + { + /* set led status */ + switch (value) + { + case 0: + /* Light off */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL; + break; + case 1: + /* Lights on */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL; + break; + default: + break; + } + } + if ( Set_led == 2 ) + { + /* set led status */ + switch (value) + { + case 0: + /* Lights off */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL; + break; + case 1: + /* Lights on */ + LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL; + break; + default: + break; + } + } +} + + + +INIT_DEVICE_EXPORT(rt_led_hw_init); +#ifdef RT_USING_FINSH +#include +void led_test(rt_uint32_t led_num, rt_uint32_t value) +{ + rt_uint8_t led_value = value; + rt_led_write(&led.parent, led_num, &led_value, 1); +} +FINSH_FUNCTION_EXPORT(led_test, e.g: led_test(0, 100).) +#endif + + + + diff --git a/bsp/lpc5410x/drivers/drv_led.h b/bsp/lpc5410x/drivers/drv_led.h new file mode 100644 index 0000000000000000000000000000000000000000..9ce2fea7bec33fb4ac4d94622688831924d5ff16 --- /dev/null +++ b/bsp/lpc5410x/drivers/drv_led.h @@ -0,0 +1,7 @@ +#ifndef __DRV_LED_H__ +#define __DRV_LED_H__ + +int rt_led_hw_init(void); +void Led_Control(rt_uint32_t Set_led, rt_uint32_t value); + +#endif diff --git a/bsp/lpc5410x/drivers/drv_uart.c b/bsp/lpc5410x/drivers/drv_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..69c2f414205b886f4ac8f888d04bd9ffb3d18c16 --- /dev/null +++ b/bsp/lpc5410x/drivers/drv_uart.c @@ -0,0 +1,333 @@ +/* + * File : drv_uart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009-2014 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 + * 2013-05-18 Bernard The first version for LPC40xx + * 2014-12-16 RT_learning The first version for LPC5410x + */ + + +#include +#include +#include + +#include "chip.h" + +static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m); +static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict); +static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev); +static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub); +static void _UART_CalcMul(UART_BAUD_T *ub); + + +struct lpc_uart +{ + LPC_USART_T *UART; + IRQn_Type UART_IRQn; +}; + + + + +static rt_err_t lpc_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct lpc_uart *uart; + + UART_BAUD_T baud; + UART_CFG_T UART_cfg; + + RT_ASSERT(serial != RT_NULL); + uart = (struct lpc_uart *)serial->parent.user_data; + + /* Initialize UART Configuration parameter structure to default state: + * Baudrate = 115200 b + * 8 data bit + * 1 Stop bit + * None parity + */ + + /* Set up baudrate parameters */ + baud.clk = Chip_Clock_GetAsyncSyscon_ClockRate(); /* Clock frequency */ + baud.baud = cfg->baud_rate; /* Required baud rate */ + baud.ovr = 0; /* Set the oversampling to the recommended rate */ + baud.mul = baud.div = 0; + + if(!baud.mul) + { + _UART_CalcMul(&baud); + } + _UART_CalcDiv(&baud); + + /* Set fractional control register */ + LPC_ASYNC_SYSCON->FRGCTRL = ((uint32_t) baud.mul << 8) | 0xFF; + + /* Configure the UART */ + UART_cfg.cfg = UART_CFG_8BIT; + UART_cfg.div = baud.div; /* Use the calculated div value */ + UART_cfg.ovr = baud.ovr; /* Use oversampling rate from baud */ + UART_cfg.res = UART_BIT_DLY(cfg->baud_rate); + + /* P254,255,246 */ + uart->UART->OSR = (UART_cfg.ovr - 1) & 0x0F; + uart->UART->BRG = (UART_cfg.div - 1) & 0xFFFF; + uart->UART->CFG = UART_CFG_ENABLE | (UART_cfg.cfg & ~UART_CFG_RES); + + + return RT_EOK; +} + + +static rt_err_t lpc_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct lpc_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct lpc_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + uart->UART->INTENCLR &= ~0x01; + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + uart->UART->INTENSET |= 0x01; + break; + } + + return RT_EOK; +} + + +static int lpc_putc(struct rt_serial_device *serial, char c) +{ + struct lpc_uart *uart; + + uart = (struct lpc_uart *)serial->parent.user_data; + while(!(uart->UART->STAT & (0x01<<2))); + + uart->UART->TXDAT = c ; + + + return 1; +} + + + +static int lpc_getc(struct rt_serial_device *serial) +{ + struct lpc_uart *uart; + + uart = (struct lpc_uart *)serial->parent.user_data; + if (uart->UART->STAT & 0x01) + return (uart->UART->RXDAT); + else + return -1; +} + +static const struct rt_uart_ops lpc_uart_ops = +{ + lpc_configure, + lpc_control, + lpc_putc, + lpc_getc, +}; + + +/* UART0 device driver structure */ +struct lpc_uart uart0 = +{ + LPC_USART0, + UART0_IRQn, +}; +struct rt_serial_device serial0; + + + +void UART0_IRQHandler(void) +{ + volatile uint32_t INTSTAT, tmp; + /* enter interrupt */ + rt_interrupt_enter(); + + INTSTAT = LPC_USART0->INTSTAT; + + INTSTAT &= 0x01; + switch (INTSTAT) + { + case 0x01: + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); + break; + default : + tmp = LPC_USART0->INTSTAT; + break; + } + /* leave interrupt */ + rt_interrupt_leave(); +} + + +void rt_hw_uart_init(void) +{ + struct lpc_uart *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + + uart = &uart0; + + serial0.ops = &lpc_uart_ops; + serial0.config = config; + serial0.parent.user_data = uart; + + /* Enable IOCON clock Then your cfg will effective P38 */ + LPC_SYSCON->AHBCLKCTRLSET[0] = (1UL << 13); + + /* Setup UART TX,RX Pin configuration cfg Pin as Tx, Rx */ + /* P63,P77 + Selects pin function 1 IOCON_FUNC1 + No addition pin function IOCON_MODE_INACT + Enables digital function by setting 1 to bit 7(default) IOCON_DIGITAL_EN + */ + LPC_IOCON->PIO[0][0] = (0x1 | (0x0 << 3) | (0x1 << 7)); + LPC_IOCON->PIO[0][1] = (0x1 | (0x0 << 3) | (0x1 << 7)); + + + /* Enable asynchronous APB bridge and subsystem P30 */ + LPC_SYSCON->ASYNCAPBCTRL = 0x01; + + /* The UART clock rate is the main system clock divided by this value P59 */ + LPC_ASYNC_SYSCON->ASYNCCLKDIV = 1; /* Set Async clock divider to 1 */ + + /* Enable peripheral clock(asynchronous APB) to UART0 P57*/ + LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1 << 0x01); + + /* Controls the clock for the Fractional Rate Generator used with the USARTs P57*/ + LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1 << 0x0F); /* Enable clock to Fractional divider */ + + + + + + /* preemption = 1, sub-priority = 1 */ + NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01)); + + /* Enable Interrupt for UART channel */ + NVIC_EnableIRQ(uart->UART_IRQn); + + /* register UART0 device */ + rt_hw_serial_register(&serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + uart); +} + + +/* PRIVATE: Division logic to divide without integer overflow */ +static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m) +{ + uint32_t q, r, u = pclk >> 24, l = pclk << 8; + m = m + 256; + q = (1 << 24) / m; + r = (1 << 24) - (q * m); + return ((q * u) << 8) + (((r * u) << 8) + l) / m; +} + +/* PRIVATE: Get highest Over sampling value */ +static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict) +{ + int32_t i, max = strict ? 16 : 5; + for (i = 16; i >= max; i--) { + if (!(val % i)) { + return i; + } + } + return 0; +} + +/* Calculate error difference */ +static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev) +{ + uint32_t err = n - (n / d) * d; + uint32_t herr = ((n / d) + 1) * d - n; + if (herr < err) { + err = herr; + } + + if (*prev <= err) { + return 0; + } + *prev = err; + return (herr == err) + 1; +} + +/* Calculate the base DIV value */ +static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub) +{ + int32_t i = 0; + uint32_t perr = ~0UL; + + if (!ub->div) { + i = ub->ovr ? ub->ovr : 16; + } + + for (; i > 4; i--) { + int32_t tmp = _CalcErr(ub->clk, ub->baud * i, &perr); + + /* Continue when no improvement seen in err value */ + if (!tmp) { + continue; + } + + ub->div = tmp - 1; + if (ub->ovr == i) { + break; + } + ub->ovr = i; + } + + if (!ub->ovr) { + return ERR_UART_BAUDRATE; + } + + ub->div += ub->clk / (ub->baud * ub->ovr); + if (!ub->div) { + return ERR_UART_BAUDRATE; + } + + ub->baud = ub->clk / (ub->div * ub->ovr); + return LPC_OK; +} + +/* Calculate the best MUL value */ +static void _UART_CalcMul(UART_BAUD_T *ub) +{ + uint32_t m, perr = ~0UL, pclk = ub->clk, ovr = ub->ovr; + + /* If clock is UART's base clock calculate only the divider */ + for (m = 0; m < 256; m++) { + uint32_t ov = ovr, x, v, tmp; + + /* Get clock and calculate error */ + x = _UART_DivClk(pclk, m); + tmp = _CalcErr(x, ub->baud, &perr); + v = (x / ub->baud) + tmp - 1; + + /* Update if new error is better than previous best */ + if (!tmp || (ovr && (v % ovr)) || + (!ovr && ((ov = _UART_GetHighDiv(v, ovr)) == 0))) { + continue; + } + + ub->ovr = ov; + ub->mul = m; + ub->clk = x; + ub->div = tmp - 1; + } +} diff --git a/bsp/lpc5410x/drivers/drv_uart.h b/bsp/lpc5410x/drivers/drv_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..9f2353f8b4d1c98dc24cc9327c7ab8c09175bb46 --- /dev/null +++ b/bsp/lpc5410x/drivers/drv_uart.h @@ -0,0 +1,10 @@ +#ifndef __DRV_UART_H_ +#define __DRV_UART_H_ + + + + +void rt_hw_uart_init(void); + + +#endif /* __BOARD_H_ */ diff --git a/bsp/lpc5410x/project.uvoptx b/bsp/lpc5410x/project.uvoptx new file mode 100644 index 0000000000000000000000000000000000000000..bf8da4518878b4b7ed89ca6ccc05d6a490899a51 --- /dev/null +++ b/bsp/lpc5410x/project.uvoptx @@ -0,0 +1,1428 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + rtthread-lpc5410x + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 8 + + + 0 + LPC812 LPCXpresso Board (LPC54xxx LPCXpresso) + http://www.nxp.com/demoboard/OM13053.html + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 12 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + CMSIS_AGDI + -X"LPC-Link-II CMSIS-DAP" -UA000000001 -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -FO7 -FD2000000 -FC1000 -FN1 -FF0LPC54xxx_512.FLM -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + + + + + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + Applications + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + 0 + applications\application.c + application.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + 0 + applications\board.c + board.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + 0 + applications\demo_thread.c + demo_thread.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + 0 + applications\startup.c + startup.c + 0 + 0 + + + + + Drivers + 0 + 0 + 0 + 0 + + 2 + 5 + 1 + 0 + 0 + 0 + 0 + drivers\drv_led.c + drv_led.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + 0 + drivers\drv_uart.c + drv_uart.c + 0 + 0 + + + + + CMSIS + 0 + 0 + 0 + 0 + + 3 + 7 + 1 + 0 + 0 + 0 + 0 + Libraries\Device\startup\sysinit.c + sysinit.c + 0 + 0 + + + 3 + 8 + 2 + 0 + 0 + 0 + 0 + Libraries\Device\startup\keil_startup_lpc5410x.s + keil_startup_lpc5410x.s + 0 + 0 + + + + + Libraries + 0 + 0 + 0 + 0 + + 4 + 9 + 4 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\power_lib\keil\lib_power.lib + lib_power.lib + 0 + 0 + + + 4 + 10 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_common\fpu_init.c + fpu_init.c + 0 + 0 + + + 4 + 11 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_common\iap.c + iap.c + 0 + 0 + + + 4 + 12 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_common\ring_buffer.c + ring_buffer.c + 0 + 0 + + + 4 + 13 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_common\rtc_ut.c + rtc_ut.c + 0 + 0 + + + 4 + 14 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\chip_5410x.c + chip_5410x.c + 0 + 0 + + + 4 + 15 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\clock_5410x.c + clock_5410x.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\crc_5410x.c + crc_5410x.c + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\fifo_5410x.c + fifo_5410x.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\gpiogroup_5410x.c + gpiogroup_5410x.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\gpio_5410x.c + gpio_5410x.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_adc.c + hw_adc.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_dmaaltd.c + hw_dmaaltd.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_dmaaltd_rom_api.c + hw_dmaaltd_rom_api.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2cmd.c + hw_i2cmd.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2cmd_rom_api.c + hw_i2cmd_rom_api.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2cmond.c + hw_i2cmond.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2cmond_rom_api.c + hw_i2cmond_rom_api.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2csd.c + hw_i2csd.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_i2csd_rom_api.c + hw_i2csd_rom_api.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_spimd.c + hw_spimd.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_spimd_rom_api.c + hw_spimd_rom_api.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_spisd.c + hw_spisd.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_spisd_rom_api.c + hw_spisd_rom_api.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\hw_uart.c + hw_uart.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\iocon_5410x.c + iocon_5410x.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\pinint_5410x.c + pinint_5410x.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\pll_5410x.c + pll_5410x.c + 0 + 0 + + + 4 + 37 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\ritimer_5410x.c + ritimer_5410x.c + 0 + 0 + + + 4 + 38 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_adc.c + romapi_adc.c + 0 + 0 + + + 4 + 39 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_dma.c + romapi_dma.c + 0 + 0 + + + 4 + 40 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_i2cm.c + romapi_i2cm.c + 0 + 0 + + + 4 + 41 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_i2cmon.c + romapi_i2cmon.c + 0 + 0 + + + 4 + 42 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_i2cs.c + romapi_i2cs.c + 0 + 0 + + + 4 + 43 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_spim.c + romapi_spim.c + 0 + 0 + + + 4 + 44 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_spis.c + romapi_spis.c + 0 + 0 + + + 4 + 45 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\romapi_uart.c + romapi_uart.c + 0 + 0 + + + 4 + 46 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\rtc_5410x.c + rtc_5410x.c + 0 + 0 + + + 4 + 47 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\sct_5410x.c + sct_5410x.c + 0 + 0 + + + 4 + 48 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\sct_pwm_5410x.c + sct_pwm_5410x.c + 0 + 0 + + + 4 + 49 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\stopwatch_5410x.c + stopwatch_5410x.c + 0 + 0 + + + 4 + 50 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\syscon_5410x.c + syscon_5410x.c + 0 + 0 + + + 4 + 51 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\sysinit_5410x.c + sysinit_5410x.c + 0 + 0 + + + 4 + 52 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\timer_5410x.c + timer_5410x.c + 0 + 0 + + + 4 + 53 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\utick_5410x.c + utick_5410x.c + 0 + 0 + + + 4 + 54 + 1 + 0 + 0 + 0 + 0 + Libraries\lpc_chip\chip_5410x\wwdt_5410x.c + wwdt_5410x.c + 0 + 0 + + + + + Kernel + 0 + 0 + 0 + 0 + + 5 + 55 + 1 + 0 + 0 + 0 + 0 + ..\..\src\clock.c + clock.c + 0 + 0 + + + 5 + 56 + 1 + 0 + 0 + 0 + 0 + ..\..\src\device.c + device.c + 0 + 0 + + + 5 + 57 + 1 + 0 + 0 + 0 + 0 + ..\..\src\idle.c + idle.c + 0 + 0 + + + 5 + 58 + 1 + 0 + 0 + 0 + 0 + ..\..\src\ipc.c + ipc.c + 0 + 0 + + + 5 + 59 + 1 + 0 + 0 + 0 + 0 + ..\..\src\irq.c + irq.c + 0 + 0 + + + 5 + 60 + 1 + 0 + 0 + 0 + 0 + ..\..\src\kservice.c + kservice.c + 0 + 0 + + + 5 + 61 + 1 + 0 + 0 + 0 + 0 + ..\..\src\mem.c + mem.c + 0 + 0 + + + 5 + 62 + 1 + 0 + 0 + 0 + 0 + ..\..\src\memheap.c + memheap.c + 0 + 0 + + + 5 + 63 + 1 + 0 + 0 + 0 + 0 + ..\..\src\mempool.c + mempool.c + 0 + 0 + + + 5 + 64 + 1 + 0 + 0 + 0 + 0 + ..\..\src\object.c + object.c + 0 + 0 + + + 5 + 65 + 1 + 0 + 0 + 0 + 0 + ..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 5 + 66 + 1 + 0 + 0 + 0 + 0 + ..\..\src\thread.c + thread.c + 0 + 0 + + + 5 + 67 + 1 + 0 + 0 + 0 + 0 + ..\..\src\timer.c + timer.c + 0 + 0 + + + + + CORTEX-M4 + 0 + 0 + 0 + 0 + + 6 + 68 + 1 + 0 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m4\cpuport.c + cpuport.c + 0 + 0 + + + 6 + 69 + 2 + 0 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m4\context_rvds.S + context_rvds.S + 0 + 0 + + + 6 + 70 + 1 + 0 + 0 + 0 + 0 + ..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 6 + 71 + 1 + 0 + 0 + 0 + 0 + ..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 6 + 72 + 1 + 0 + 0 + 0 + 0 + ..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 7 + 73 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 7 + 74 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 7 + 75 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 7 + 76 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 7 + 77 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\portal.c + portal.c + 0 + 0 + + + 7 + 78 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 7 + 79 + 1 + 0 + 0 + 0 + 0 + ..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 8 + 80 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 8 + 81 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\symbol.c + symbol.c + 0 + 0 + + + 8 + 82 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 8 + 83 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_compiler.c + finsh_compiler.c + 0 + 0 + + + 8 + 84 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_error.c + finsh_error.c + 0 + 0 + + + 8 + 85 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_heap.c + finsh_heap.c + 0 + 0 + + + 8 + 86 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_init.c + finsh_init.c + 0 + 0 + + + 8 + 87 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_node.c + finsh_node.c + 0 + 0 + + + 8 + 88 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_ops.c + finsh_ops.c + 0 + 0 + + + 8 + 89 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_parser.c + finsh_parser.c + 0 + 0 + + + 8 + 90 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_var.c + finsh_var.c + 0 + 0 + + + 8 + 91 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_vm.c + finsh_vm.c + 0 + 0 + + + 8 + 92 + 1 + 0 + 0 + 0 + 0 + ..\..\components\finsh\finsh_token.c + finsh_token.c + 0 + 0 + + + +
diff --git a/bsp/lpc5410x/project.uvprojx b/bsp/lpc5410x/project.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..a33a383a9bd7b1a3a287b2b3c385be97b41ce395 --- /dev/null +++ b/bsp/lpc5410x/project.uvprojx @@ -0,0 +1,916 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-lpc5410x + 0x4 + ARM-ADS + + + LPC54102:M4 + NXP + Keil.LPC54000_DFP.1.0.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x02000000,0x10000) IRAM2(0x02010000,0x08000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + 0 + $$Device:LPC54102$Device\Include\LPC54xxx.h + + + + + + + + + + $$Device:LPC54102$SVD\LPC5410x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-lpc5410x + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + 12 + + + + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4104 + + 0 + BIN\CMSIS_AGDI.dll + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 0 + 0x2010000 + 0x8000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + + + CORE_M4 + +<<<<<<< HEAD + .;..\..\components\drivers\include;..\..\components\finsh;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m4;Libraries\CMSIS\Include;Libraries\lpc_chip\chip_5410x;Libraries\lpc_chip\chip_5410x\config;Libraries\lpc_chip\chip_common;applications;drivers +======= + applications;.;drivers;Libraries\CMSIS\Include;Libraries\lpc_chip\chip_common;Libraries\lpc_chip\chip_5410x;Libraries\lpc_chip\chip_5410x\config;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh +>>>>>>> f68b03f089805f585e6f634b0db80e377344c21d + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x02000000 + + + + + --keep __fsym_* --keep __vsym_* + + + + + + + + Applications + + + application.c + 1 + applications\application.c + + + board.c + 1 + applications\board.c + + + demo_thread.c + 1 + applications\demo_thread.c + + + startup.c + 1 + applications\startup.c + + + + + Drivers + + + drv_led.c + 1 + drivers\drv_led.c + + + drv_uart.c + 1 + drivers\drv_uart.c + + + + + CMSIS + + + sysinit.c + 1 + Libraries\Device\startup\sysinit.c + + + keil_startup_lpc5410x.s + 2 + Libraries\Device\startup\keil_startup_lpc5410x.s + + + + + Libraries + + + lib_power.lib + 4 + Libraries\lpc_chip\chip_5410x\power_lib\keil\lib_power.lib + + + fpu_init.c + 1 + Libraries\lpc_chip\chip_common\fpu_init.c + + + iap.c + 1 + Libraries\lpc_chip\chip_common\iap.c + + + ring_buffer.c + 1 + Libraries\lpc_chip\chip_common\ring_buffer.c + + + rtc_ut.c + 1 + Libraries\lpc_chip\chip_common\rtc_ut.c + + + chip_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\chip_5410x.c + + + clock_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\clock_5410x.c + + + crc_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\crc_5410x.c + + + fifo_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\fifo_5410x.c + + + gpiogroup_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\gpiogroup_5410x.c + + + gpio_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\gpio_5410x.c + + + hw_adc.c + 1 + Libraries\lpc_chip\chip_5410x\hw_adc.c + + + hw_dmaaltd.c + 1 + Libraries\lpc_chip\chip_5410x\hw_dmaaltd.c + + + hw_dmaaltd_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_dmaaltd_rom_api.c + + + hw_i2cmd.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2cmd.c + + + hw_i2cmd_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2cmd_rom_api.c + + + hw_i2cmond.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2cmond.c + + + hw_i2cmond_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2cmond_rom_api.c + + + hw_i2csd.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2csd.c + + + hw_i2csd_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_i2csd_rom_api.c + + + hw_spimd.c + 1 + Libraries\lpc_chip\chip_5410x\hw_spimd.c + + + hw_spimd_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_spimd_rom_api.c + + + hw_spisd.c + 1 + Libraries\lpc_chip\chip_5410x\hw_spisd.c + + + hw_spisd_rom_api.c + 1 + Libraries\lpc_chip\chip_5410x\hw_spisd_rom_api.c + + + hw_uart.c + 1 + Libraries\lpc_chip\chip_5410x\hw_uart.c + + + iocon_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\iocon_5410x.c + + + pinint_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\pinint_5410x.c + + + pll_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\pll_5410x.c + + + ritimer_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\ritimer_5410x.c + + + romapi_adc.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_adc.c + + + romapi_dma.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_dma.c + + + romapi_i2cm.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_i2cm.c + + + romapi_i2cmon.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_i2cmon.c + + + romapi_i2cs.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_i2cs.c + + + romapi_spim.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_spim.c + + + romapi_spis.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_spis.c + + + romapi_uart.c + 1 + Libraries\lpc_chip\chip_5410x\romapi_uart.c + + + rtc_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\rtc_5410x.c + + + sct_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\sct_5410x.c + + + sct_pwm_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\sct_pwm_5410x.c + + + stopwatch_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\stopwatch_5410x.c + + + syscon_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\syscon_5410x.c + + + sysinit_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\sysinit_5410x.c + + + timer_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\timer_5410x.c + + + utick_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\utick_5410x.c + + + wwdt_5410x.c + 1 + Libraries\lpc_chip\chip_5410x\wwdt_5410x.c + + + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c + + + device.c + 1 + ..\..\src\device.c + + + idle.c + 1 + ..\..\src\idle.c + + + ipc.c + 1 + ..\..\src\ipc.c + + + irq.c + 1 + ..\..\src\irq.c + + + kservice.c + 1 + ..\..\src\kservice.c + + + mem.c + 1 + ..\..\src\mem.c + + + memheap.c + 1 + ..\..\src\memheap.c + + + mempool.c + 1 + ..\..\src\mempool.c + + + object.c + 1 + ..\..\src\object.c + + + scheduler.c + 1 + ..\..\src\scheduler.c + + + thread.c + 1 + ..\..\src\thread.c + + + timer.c + 1 + ..\..\src\timer.c + + + + + CORTEX-M4 + + + cpuport.c + 1 + ..\..\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m4\context_rvds.S + + + backtrace.c + 1 + ..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\libcpu\arm\common\showmem.c + + + + + DeviceDrivers + + + serial.c + 1 + ..\..\components\drivers\serial\serial.c + + + completion.c + 1 + ..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\components\drivers\src\pipe.c + + + portal.c + 1 + ..\..\components\drivers\src\portal.c + + + ringbuffer.c + 1 + ..\..\components\drivers\src\ringbuffer.c + + + workqueue.c + 1 + ..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\components\finsh\shell.c + + + symbol.c + 1 + ..\..\components\finsh\symbol.c + + + cmd.c + 1 + ..\..\components\finsh\cmd.c + + + finsh_compiler.c + 1 + ..\..\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\components\finsh\finsh_token.c + + + + + + + +
diff --git a/bsp/lpc5410x/rtconfig.h b/bsp/lpc5410x/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..94ac2093cdacdfa5ca0068694ccf6625ab724e05 --- /dev/null +++ b/bsp/lpc5410x/rtconfig.h @@ -0,0 +1,206 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +// + +// +#define RT_NAME_MAX 8 +// +#define RT_ALIGN_SIZE 4 +// +// 8 +// 32 +// 256 +// +#define RT_THREAD_PRIORITY_MAX 32 +// +#define RT_TICK_PER_SECOND 100 +//
+#define RT_DEBUG +// +// #define RT_THREAD_DEBUG +// +#define RT_USING_OVERFLOW_CHECK +//
+ +// +#define RT_USING_HOOK +//
+// #define RT_USING_TIMER_SOFT +// +#define RT_TIMER_THREAD_PRIO 4 +// +#define RT_TIMER_THREAD_STACK_SIZE 512 +// +#define RT_TIMER_TICK_PER_SECOND 10 +//
+ +//
+// +#define RT_USING_SEMAPHORE +// +#define RT_USING_MUTEX +// +#define RT_USING_EVENT +// +#define RT_USING_MAILBOX +// +#define RT_USING_MESSAGEQUEUE +//
+ +//
+// +#define RT_USING_MEMPOOL +// +#define RT_USING_MEMHEAP +// +#define RT_USING_HEAP +// +#define RT_USING_SMALL_MEM +// +// #define RT_USING_SLAB +//
+ +//
+#define RT_USING_DEVICE +// +#define RT_USING_DEVICE_IPC +// +#define RT_USING_SERIAL +//
+ +//
+#define RT_USING_CONSOLE +// +#define RT_CONSOLEBUF_SIZE 128 +//
+ +// +// #define RT_USING_COMPONENTS_INIT +//
+#define RT_USING_FINSH +// +#define FINSH_USING_SYMTAB +// +#define FINSH_USING_DESCRIPTION +// +#define FINSH_THREAD_STACK_SIZE 4096 +//
+ +//
+// +// #define RT_USING_NEWLIB +// +// #define RT_USING_PTHREADS +//
+ +//
+// #define RT_USING_DFS +// +// #define DFS_USING_WORKDIR +// +#define DFS_FILESYSTEMS_MAX 2 +// +#define DFS_FD_MAX 4 +// +#define RT_USING_DFS_ELMFAT +// +// 1 +// 2 +// +#define RT_DFS_ELM_USE_LFN 1 +// +#define RT_DFS_ELM_MAX_LFN 64 +// +// #define RT_USING_DFS_YAFFS2 +// +// #define RT_USING_DFS_UFFS +// +// #define RT_USING_DFS_DEVFS +// +// #define RT_USING_DFS_NFS +// +#define RT_NFS_HOST_EXPORT "192.168.1.5:/" +//
+ +//
+// #define RT_USING_LWIP +// +#define RT_LWIP_ICMP +// +// #define RT_LWIP_IGMP +// +#define RT_LWIP_UDP +// +#define RT_LWIP_TCP +// +#define RT_LWIP_DNS +// +#define RT_LWIP_PBUF_NUM 4 +// +#define RT_LWIP_TCP_PCB_NUM 3 +// +#define RT_LWIP_TCP_SND_BUF 2048 +// +#define RT_LWIP_TCP_WND 2048 +// +// #define RT_LWIP_SNMP +// +// #define RT_LWIP_DHCP +// +#define RT_LWIP_TCPTHREAD_PRIORITY 12 +// +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 +// +#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 +// +#define RT_LWIP_ETHTHREAD_PRIORITY 14 +// +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 +// +#define RT_LWIP_ETHTHREAD_STACKSIZE 512 +// +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 1 +#define RT_LWIP_IPADDR3 30 +// +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 1 +#define RT_LWIP_GWADDR3 1 +// +#define RT_LWIP_MSKADDR0 255 +#define RT_LWIP_MSKADDR1 255 +#define RT_LWIP_MSKADDR2 255 +#define RT_LWIP_MSKADDR3 0 +//
+ +//
+// #define RT_USING_RTGUI +// +#define RTGUI_NAME_MAX 12 +// +#define RTGUI_USING_SMALL_SIZE +// +#define RTGUI_USING_FONT16 +// +// #define RTGUI_USING_FONT12 +// +#define RTGUI_USING_FONTHZ +// +#define RTGUI_DEFAULT_FONT_SIZE 16 +// +// #define RTGUI_USING_DFS_FILERW +// +#define RTGUI_USING_HZ_BMP +// +// #define RTGUI_USING_HZ_FILE +// +// #define RTGUI_USING_MOUSE_CURSOR +//
+ +//
+ +#endif diff --git a/bsp/lpc5410x/rtconfig.py b/bsp/lpc5410x/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..555a1b49623d6a75972113028a00206a310c7b1a --- /dev/null +++ b/bsp/lpc5410x/rtconfig.py @@ -0,0 +1,87 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='gcc' +BOARD_NAME = 'lpc5410x' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'D:/Program Files/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'D:/Keil_v5' +elif CROSS_TOOL == 'iar': + print '================ERROR============================' + print 'Not support iar yet!' + print '=================================================' + exit(0) + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'g++' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -g -Wall ' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -lm -lgcc -lc' + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread-' + BOARD_NAME +'.map,-cref,-u,Reset_Handler -T rtthread-' + BOARD_NAME + '.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + CXX = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4.fp' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread_' + \ + BOARD_NAME + '.map --scatter rtthread-' + BOARD_NAME + '.sct' + + CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' + CXXFLAGS = CFLAGS + + EXEC_PATH += '/arm/bin40/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' diff --git a/bsp/lpc5410x/rtthread-lpc5410x.ld b/bsp/lpc5410x/rtthread-lpc5410x.ld new file mode 100644 index 0000000000000000000000000000000000000000..4e81c252f9a4ae3ffd19550955cbd1568dfa5b64 --- /dev/null +++ b/bsp/lpc5410x/rtthread-lpc5410x.ld @@ -0,0 +1,79 @@ +/* + * - Up to 512 kB on-chip flash memory + * - Up to 96 kB main SRAM. + * - An additional 8 kB SRAM. with GNU ld + * Date Author Notes + * 2014-11-02 aozima first implementation + * 2014-12-16 RT_learning change little for support LPC5410x + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K /* */ + SRAM (rwx) : ORIGIN = 0x02000000, LENGTH = 96K +} + +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + + /* 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 components init. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + } > FLASH + + /* .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 = .; + } > FLASH + __exidx_end = .; + + /* end of all text. */ + _etext = .; + + .data : AT(_etext) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + __bss_end = .; + +} diff --git a/bsp/lpc5410x/rtthread-lpc5410x.sct b/bsp/lpc5410x/rtthread-lpc5410x.sct new file mode 100644 index 0000000000000000000000000000000000000000..5a8994db988ecd39e0161aee51ad6f4a26421568 --- /dev/null +++ b/bsp/lpc5410x/rtthread-lpc5410x.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x00000000 0x00080000 { ; load region size_region + ER_IROM1 0x00000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x02000000 0x00010000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/lpc5410x/template.uvoptx b/bsp/lpc5410x/template.uvoptx new file mode 100644 index 0000000000000000000000000000000000000000..203aed67e1563f42a7e55f5bd16efb41c3d174da --- /dev/null +++ b/bsp/lpc5410x/template.uvoptx @@ -0,0 +1,176 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + rtthread-lpc5410x + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 8 + + + 0 + LPC812 LPCXpresso Board (LPC54xxx LPCXpresso) + http://www.nxp.com/demoboard/OM13053.html + + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 14 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + CMSIS_AGDI + -X"LPC-Link-II CMSIS-DAP" -UA000000001 -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -FO7 -FD2000000 -FC1000 -FN1 -FF0LPC54xxx_512.FLM -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + + + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + + + + + + +
diff --git a/bsp/lpc5410x/template.uvprojx b/bsp/lpc5410x/template.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..6f22c6f1a2832bd910fa2d5cdbff3930d99f28e9 --- /dev/null +++ b/bsp/lpc5410x/template.uvprojx @@ -0,0 +1,393 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-lpc5410x + 0x4 + ARM-ADS + + + LPC54102:M4 + NXP + IROM(0x00000000,0x80000) IRAM(0x02000000,0x10000) IRAM2(0x02010000,0x08000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD02000000 -FC1000 -FN1 -FF0LPC54xxx_512 -FS00 -FL080000 -FP0($$Device:LPC54102$Flash\LPC54xxx_512.FLM)) + 0 + $$Device:LPC54102$Device\Include\LPC54xxx.h + + + + + + + + + + $$Device:LPC54102$SVD\LPC5410x.svd + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-lpc5410x + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + + 0 + 14 + + + + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4104 + + BIN\CMSIS_AGDI.dll + "" () + + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x2000000 + 0x10000 + + + 0 + 0x2010000 + 0x8000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x02000000 + + + + + + + + + + + + +