diff --git a/bsp/lpc408x/Libraries/CMSIS/Include/arm_common_tables.h b/bsp/lpc408x/Libraries/CMSIS/Include/arm_common_tables.h new file mode 100644 index 0000000000000000000000000000000000000000..7245c4f12bbc7b0cb1d9df77b62725fe84ce1454 --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/arm_common_tables.h @@ -0,0 +1,35 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010 ARM Limited. All rights reserved. +* +* $Date: 11. November 2010 +* $Revision: V1.0.2 +* +* 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 +* +* Version 1.0.2 2010/11/11 +* Documentation updated. +* +* Version 1.0.1 2010/10/05 +* Production release and review comments incorporated. +* +* Version 1.0.0 2010/09/20 +* Production release and review comments incorporated. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern uint16_t armBitRevTable[256]; +extern q15_t armRecipTableQ15[64]; +extern q31_t armRecipTableQ31[64]; +extern const q31_t realCoefAQ31[1024]; +extern const q31_t realCoefBQ31[1024]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/bsp/lpc408x/Libraries/CMSIS/Include/arm_math.h b/bsp/lpc408x/Libraries/CMSIS/Include/arm_math.h new file mode 100644 index 0000000000000000000000000000000000000000..b33ae193707d851f9824b7fe6bc3bd79d954bfad --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/arm_math.h @@ -0,0 +1,7062 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * $Date: 15. July 2011 + * $Revision: V1.0.10 + * + * Project: CMSIS DSP Library + * Title: arm_math.h + * + * Description: Public header file for CMSIS DSP Library + * + * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 + * + * Version 1.0.10 2011/7/15 + * Big Endian support added and Merged M0 and M3/M4 Source code. + * + * Version 1.0.3 2010/11/29 + * Re-organized the CMSIS folders and updated documentation. + * + * Version 1.0.2 2010/11/11 + * Documentation updated. + * + * Version 1.0.1 2010/10/05 + * Production release and review comments incorporated. + * + * Version 1.0.0 2010/09/20 + * Production release and review comments incorporated. + * -------------------------------------------------------------------- */ + +/** + \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 modules 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. + * + * Processor Support + * + * The library is completely written in C and is fully CMSIS compliant. + * High performance is achieved through maximum use of Cortex-M4 intrinsics. + * + * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor, + * with the DSP intrinsics being emulated through software. + * + * + * Toolchain Support + * + * The library has been developed and tested with MDK-ARM version 4.21. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * 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 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. + * + * 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 + * + * Each library project have differant pre-processor macros. + * + * 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_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 for checking on the input and output sizes of matrices + * + * ARM_MATH_ROUNDING: + * Define macro for rounding on support functions + * + * __FPU_PRESENT: + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + * + * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above. + * + * Copyright Notice + * + * Copyright (C) 2010 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + * @ingroup DSP_Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * @ingroup DSP_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 + * @ingroup DSP_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 + * @ingroup DSP_Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * @ingroup DSP_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 + * @ingroup DSP_Functions + */ + +/** + * @defgroup groupController Controller Functions + * @ingroup DSP_Functions + */ + +/** + * @defgroup groupStats Statistics Functions + * @ingroup DSP_Functions + */ +/** + * @defgroup groupSupport Support Functions + * @ingroup DSP_Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * @ingroup DSP_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 + * @ingroup DSP_Lib + */ +#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" +#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 +#define PI 3.14159265358979f + + /** + * @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 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. + */ +#define __SIMD32(addr) (*(int32_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + /** + * @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) ) + +#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) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0) && ((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) + + 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 */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + + /* + * @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 = (char) x; + s = (char) 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 = (char) x; + s = (char) 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))); + } + + + + +#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */ + + + /** + * @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 + * @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 + 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; + float32_t x1; + float32_t 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 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; + + /** + * @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; + + /** + * @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; + + /** + * @brief Processing function for the Q15 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Initialization function for the Q15 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Initialization function for the Q31 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point CFFT/CIFFT. + * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Initialization function for the floating-point CFFT/CIFFT. + * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + + /*---------------------------------------------------------------------- + * Internal functions prototypes FFT function + ----------------------------------------------------------------------*/ + + /** + * @brief Core function for the floating-point CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to the twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the floating-point CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @param[in] onebyfftLen value of 1/fftLen. + * @return none. + */ + + void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftSize length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. + * @param[in] *pBitRevTab points to the bit reversal table. + * @return none. + */ + + void arm_bitreversal_f32( + float32_t *pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q31 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q31( + q31_t *pSrc, + uint32_t fftLen, + q31_t *pCoef, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q31 CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q15 CFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q15 CIFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @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; + + /** + * @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; + + /** + * @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; + + /** + * @brief Processing function for the Q15 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Initialization function for the Q15 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + 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); + + /** + * @brief Processing function for the Q31 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Initialization function for the Q31 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + 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); + + /** + * @brief Initialization function for the floating-point RFFT/RIFFT. + * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + 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); + + /** + * @brief Processing function for the floating-point RFFT/RIFFT. + * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @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 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 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. + * @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. + * @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 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. + * @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. + * @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 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. + * @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; + + /* Implementation of PID controller */ + + #ifdef ARM_MATH_CM0 + + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0 )* in ; + + #else + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + + #endif + + #ifdef ARM_MATH_CM0 + + /* 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] ; + + #else + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc); + + #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 = (x - S->x1) / xSpacing; + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if(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 >= (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 >= (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 */ + 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 >= (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 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 + */ + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + + +/** + * + * End of file. + */ diff --git a/bsp/lpc408x/Libraries/CMSIS/Include/core_cm0.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000000000000000000000000000000000000..9d7a19f9ae1218784a8e0e4b4defdc9359a1b245 --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm0.h @@ -0,0 +1,665 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#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 + + +/** \mainpage CMSIS Cortex-M0 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + + The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x10) /*!< [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 core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#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__ ) + /* add preprocessor checks */ +#endif + +#include /*!< standard types definitions */ +#include "core_cmInstr.h" /*!< Core Instruction Access */ +#include "core_cmFunc.h" /*!< 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) */ +#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 CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \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 CMSIS NVIC + Type definitions for the Cortex-M 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 CMSIS SCB + Type definitions for the Cortex-M 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 CMSIS SysTick + Type definitions for the Cortex-M 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 CMSIS Core Debug + 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 + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space 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 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 + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/* 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 + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \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 + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \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 + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + This function initiate 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 CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + 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/lpc408x/Libraries/CMSIS/Include/core_cm3.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000000000000000000000000000000000000..e6b14fc28359660c8c29b3f4b90a6dfc4e75fdbf --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm3.h @@ -0,0 +1,1240 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#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 + + +/** \mainpage CMSIS Cortex-M3 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + + The CMSIS Cortex-M3 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + * @ingroup CMSIS_Core + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + * @ingroup CMSIS_Core + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x10) /*!< [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 core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ +#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__ ) + /* add preprocessor checks */ +#endif + +#include /*!< standard types definitions */ +#include "core_cmInstr.h" /*!< Core Instruction Access */ +#include "core_cmFunc.h" /*!< 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) */ +#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 CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + * @ingroup CMSIS_Core + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \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 CMSIS NVIC + Type definitions for the Cortex-M 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 CMSIS SCB + Type definitions for the Cortex-M 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 CMSIS System Control and ID Register not in the SCB + Type definitions for the Cortex-M 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 CMSIS SysTick + Type definitions for the Cortex-M 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 CMSIS ITM + Type definitions for the Cortex-M 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 */ +} 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_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA 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 */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU CMSIS MPU + Type definitions for the Cortex-M 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_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 CMSIS Core Debug + Type definitions for the Cortex-M 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 + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM 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 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 + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + * @ingroup CMSIS_Core + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/** \brief Set Priority Grouping + + This 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 + + This function gets the priority grouping from NVIC Interrupt Controller. + Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + + \return Priority grouping 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 + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +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 + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +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 + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \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 + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +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 + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +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 + + This function reads the active register in NVIC and returns the active bit. + \param [in] IRQn Number of the interrupt for get active + \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 + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \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 + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +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 + + This function encodes the priority for an interrupt with the given priority group, + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The returned priority value can be used for NVIC_SetPriority(...) function + + \param [in] PriorityGroup Used priority group + \param [in] PreemptPriority Preemptive priority value (starting from 0) + \param [in] SubPriority Sub priority value (starting from 0) + \return Encoded priority for the interrupt + */ +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 + + This function decodes an interrupt priority value with the given priority group to + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The priority value can be retrieved with NVIC_GetPriority(...) function + + \param [in] Priority Priority value + \param [in] PriorityGroup Used priority group + \param [out] pPreemptPriority Preemptive priority value (starting from 0) + \param [out] pSubPriority Sub priority 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 + + This function initiate 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 CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + 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 CMSIS Core Debug Functions + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** \brief ITM Send Character + + This function transmits a character via the ITM channel 0. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \param [in] ch Character to transmit + \return Character to transmit + */ +static __INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ + (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 + + This function inputs a character via external variable ITM_RxBuffer. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \return Received character + \return -1 No character received + */ +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 + + This function checks external variable ITM_RxBuffer whether a character is available or not. + It returns '1' if a character is available and '0' if no character is available. + + \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/lpc408x/Libraries/CMSIS/Include/core_cm4.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000000000000000000000000000000000000..bf022ba67fb405b50503be85bd55ba0ffffe2b8b --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm4.h @@ -0,0 +1,1378 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ +#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 + + +/** \mainpage CMSIS Cortex-M4 + + This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. + It consists of: + + - Cortex-M Core Register Definitions + - Cortex-M functions + - Cortex-M instructions + - Cortex-M SIMD instructions + + The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease + access to the Cortex-M Core + */ + +/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions + CMSIS violates following MISRA-C2004 Rules: + + - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \defgroup CMSIS_core_definitions CMSIS Core Definitions + This file defines all structures and symbols for CMSIS core: + - CMSIS version number + - Cortex-M core + - Cortex-M core Revision Number + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [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 core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + +/*!< __FPU_USED 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 ( __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__ ) + /* add preprocessor checks to define __FPU_USED */ + #define __FPU_USED 0 +#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) */ +#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 CMSIS_core_definitions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ +/** \defgroup CMSIS_core_register CMSIS Core Register + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE CMSIS Core + Type definitions for the Cortex-M Core Registers + @{ + */ + +/** \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 CMSIS NVIC + Type definitions for the Cortex-M 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 CMSIS SCB + Type definitions for the Cortex-M 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 CMSIS System Control and ID Register not in the SCB + Type definitions for the Cortex-M 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 CMSIS SysTick + Type definitions for the Cortex-M 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 CMSIS ITM + Type definitions for the Cortex-M 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 */ +} 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_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA 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 */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU CMSIS MPU + Type definitions for the Cortex-M 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_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 CMSIS FPU + Type definitions for the Cortex-M 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 CMSIS Core Debug + Type definitions for the Cortex-M 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 + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM 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 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 + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions + @{ + */ + +/** \brief Set Priority Grouping + + This 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 + + This function gets the priority grouping from NVIC Interrupt Controller. + Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + + \return Priority grouping 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 + + This function enables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to enable + */ +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 + + This function disables a device specific interrupt in the NVIC interrupt controller. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the external interrupt to disable + */ +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 + + This function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Number of the interrupt for get pending + \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 + + This function sets the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for set pending + */ +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 + + This function clears the pending bit for the specified interrupt. + The interrupt number cannot be a negative value. + + \param [in] IRQn Number of the interrupt for clear pending + */ +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 + + This function reads the active register in NVIC and returns the active bit. + \param [in] IRQn Number of the interrupt for get active + \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 + + This function sets the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + Note: The priority cannot be set for every core interrupt. + + \param [in] IRQn Number of the interrupt for set priority + \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 + + This function reads the priority for the specified interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + The returned priority value is automatically aligned to the implemented + priority bits of the microcontroller. + + \param [in] IRQn Number of the interrupt for get priority + \return Interrupt Priority + */ +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 + + This function encodes the priority for an interrupt with the given priority group, + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The returned priority value can be used for NVIC_SetPriority(...) function + + \param [in] PriorityGroup Used priority group + \param [in] PreemptPriority Preemptive priority value (starting from 0) + \param [in] SubPriority Sub priority value (starting from 0) + \return Encoded priority for the interrupt + */ +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 + + This function decodes an interrupt priority value with the given priority group to + preemptive priority value and sub priority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + The priority value can be retrieved with NVIC_GetPriority(...) function + + \param [in] Priority Priority value + \param [in] PriorityGroup Used priority group + \param [out] pPreemptPriority Preemptive priority value (starting from 0) + \param [out] pSubPriority Sub priority 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 + + This function initiate 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 CMSIS Core SysTick Functions + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + This function initialises the system tick timer and its interrupt and start the system tick timer. + Counter is in free running mode to generate periodical interrupts. + + \param [in] ticks Number of ticks between two interrupts + \return 0 Function succeeded + \return 1 Function failed + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + 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 CMSIS Core Debug Functions + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ + + +/** \brief ITM Send Character + + This function transmits a character via the ITM channel 0. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \param [in] ch Character to transmit + \return Character to transmit + */ +static __INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ + (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 + + This function inputs a character via external variable ITM_RxBuffer. + It just returns when no debugger is connected that has booked the output. + It is blocking when a debugger is connected, but the previous character send is not transmitted. + + \return Received character + \return -1 No character received + */ +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 + + This function checks external variable ITM_RxBuffer whether a character is available or not. + It returns '1' if a character is available and '0' if no character is available. + + \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/lpc408x/Libraries/CMSIS/Include/core_cm4_simd.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm4_simd.h new file mode 100644 index 0000000000000000000000000000000000000000..e7b6765225e1f247ce9bebcd9f0ba0739dad566d --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cm4_simd.h @@ -0,0 +1,701 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#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 SOMD 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) ) + + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + +/*------ CM4 SIMDDSP Intrinsics -----------------------------------------------------*/ +/* intrinsic __SADD8 see intrinsics.h */ +/* intrinsic __QADD8 see intrinsics.h */ +/* intrinsic __SHADD8 see intrinsics.h */ +/* intrinsic __UADD8 see intrinsics.h */ +/* intrinsic __UQADD8 see intrinsics.h */ +/* intrinsic __UHADD8 see intrinsics.h */ +/* intrinsic __SSUB8 see intrinsics.h */ +/* intrinsic __QSUB8 see intrinsics.h */ +/* intrinsic __SHSUB8 see intrinsics.h */ +/* intrinsic __USUB8 see intrinsics.h */ +/* intrinsic __UQSUB8 see intrinsics.h */ +/* intrinsic __UHSUB8 see intrinsics.h */ +/* intrinsic __SADD16 see intrinsics.h */ +/* intrinsic __QADD16 see intrinsics.h */ +/* intrinsic __SHADD16 see intrinsics.h */ +/* intrinsic __UADD16 see intrinsics.h */ +/* intrinsic __UQADD16 see intrinsics.h */ +/* intrinsic __UHADD16 see intrinsics.h */ +/* intrinsic __SSUB16 see intrinsics.h */ +/* intrinsic __QSUB16 see intrinsics.h */ +/* intrinsic __SHSUB16 see intrinsics.h */ +/* intrinsic __USUB16 see intrinsics.h */ +/* intrinsic __UQSUB16 see intrinsics.h */ +/* intrinsic __UHSUB16 see intrinsics.h */ +/* intrinsic __SASX see intrinsics.h */ +/* intrinsic __QASX see intrinsics.h */ +/* intrinsic __SHASX see intrinsics.h */ +/* intrinsic __UASX see intrinsics.h */ +/* intrinsic __UQASX see intrinsics.h */ +/* intrinsic __UHASX see intrinsics.h */ +/* intrinsic __SSAX see intrinsics.h */ +/* intrinsic __QSAX see intrinsics.h */ +/* intrinsic __SHSAX see intrinsics.h */ +/* intrinsic __USAX see intrinsics.h */ +/* intrinsic __UQSAX see intrinsics.h */ +/* intrinsic __UHSAX see intrinsics.h */ +/* intrinsic __USAD8 see intrinsics.h */ +/* intrinsic __USADA8 see intrinsics.h */ +/* intrinsic __SSAT16 see intrinsics.h */ +/* intrinsic __USAT16 see intrinsics.h */ +/* intrinsic __UXTB16 see intrinsics.h */ +/* intrinsic __SXTB16 see intrinsics.h */ +/* intrinsic __UXTAB16 see intrinsics.h */ +/* intrinsic __SXTAB16 see intrinsics.h */ +/* intrinsic __SMUAD see intrinsics.h */ +/* intrinsic __SMUADX see intrinsics.h */ +/* intrinsic __SMLAD see intrinsics.h */ +/* intrinsic __SMLADX see intrinsics.h */ +/* intrinsic __SMLALD see intrinsics.h */ +/* intrinsic __SMLALDX see intrinsics.h */ +/* intrinsic __SMUSD see intrinsics.h */ +/* intrinsic __SMUSDX see intrinsics.h */ +/* intrinsic __SMLSD see intrinsics.h */ +/* intrinsic __SMLSDX see intrinsics.h */ +/* intrinsic __SMLSLD see intrinsics.h */ +/* intrinsic __SMLSLDX see intrinsics.h */ +/* intrinsic __SEL see intrinsics.h */ +/* intrinsic __QADD see intrinsics.h */ +/* intrinsic __QSUB see intrinsics.h */ +/* intrinsic __PKHBT see intrinsics.h */ +/* intrinsic __PKHTB see intrinsics.h */ + +/*-- 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; \ + }) + +/*-- 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/lpc408x/Libraries/CMSIS/Include/core_cmFunc.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cmFunc.h new file mode 100644 index 0000000000000000000000000000000000000000..88819f9dd116dfdb713bf298e517870f1ba194ef --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cmFunc.h @@ -0,0 +1,609 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V2.10 + * @date 26. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#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 ISPR Register + + This function returns the content of the ISPR Register. + + \return ISPR 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 ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** \brief Get ISPR Register + + This function returns the content of the ISPR Register. + + \return ISPR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/bsp/lpc408x/Libraries/CMSIS/Include/core_cmInstr.h b/bsp/lpc408x/Libraries/CMSIS/Include/core_cmInstr.h new file mode 100644 index 0000000000000000000000000000000000000000..56d5ac75cd59ff3d657b3707f913aa913b8d318e --- /dev/null +++ b/bsp/lpc408x/Libraries/CMSIS/Include/core_cmInstr.h @@ -0,0 +1,586 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V2.10 + * @date 19. July 2011 + * + * @note + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + * @ingroup CMSIS_Core + 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 + */ +static __INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} + + +/** \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 + */ +static __INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} + + +#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 ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) static __INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) static __INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) static __INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) static __INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) static __INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC177x_8x.h b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC177x_8x.h new file mode 100644 index 0000000000000000000000000000000000000000..5ebe1428d4cef6d6d0f86d4c9e770832d39cacf0 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC177x_8x.h @@ -0,0 +1,1442 @@ +/********************************************************************** +* $Id$ LPC177x_8x.h 2011-06-02 +*//** +* @file LPC177x_8x.h +* @brief Cortex-M3 Core Peripheral Access Layer Header File for +* NXP LPC177x_8x Series. +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 __LPC177x_8x_H__ +#define __LPC177x_8x_H__ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC177x_8x Specific Interrupt Numbers *******************************************************/ + WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */ + TIMER0_IRQn = 1, /*!< Timer0 Interrupt */ + TIMER1_IRQn = 2, /*!< Timer1 Interrupt */ + TIMER2_IRQn = 3, /*!< Timer2 Interrupt */ + TIMER3_IRQn = 4, /*!< Timer3 Interrupt */ + UART0_IRQn = 5, /*!< UART0 Interrupt */ + UART1_IRQn = 6, /*!< UART1 Interrupt */ + UART2_IRQn = 7, /*!< UART2 Interrupt */ + UART3_IRQn = 8, /*!< UART3 Interrupt */ + PWM1_IRQn = 9, /*!< PWM1 Interrupt */ + I2C0_IRQn = 10, /*!< I2C0 Interrupt */ + I2C1_IRQn = 11, /*!< I2C1 Interrupt */ + I2C2_IRQn = 12, /*!< I2C2 Interrupt */ + Reserved0_IRQn = 13, /*!< Reserved */ + SSP0_IRQn = 14, /*!< SSP0 Interrupt */ + SSP1_IRQn = 15, /*!< SSP1 Interrupt */ + PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */ + RTC_IRQn = 17, /*!< Real Time Clock Interrupt */ + EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */ + EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */ + EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */ + EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */ + ADC_IRQn = 22, /*!< A/D Converter Interrupt */ + BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */ + USB_IRQn = 24, /*!< USB Interrupt */ + CAN_IRQn = 25, /*!< CAN Interrupt */ + DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */ + I2S_IRQn = 27, /*!< I2S Interrupt */ + ENET_IRQn = 28, /*!< Ethernet Interrupt */ + MCI_IRQn = 29, /*!< SD/MMC card I/F Interrupt */ + MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */ + QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */ + PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */ + USBActivity_IRQn = 33, /*!< USB Activity interrupt */ + CANActivity_IRQn = 34, /*!< CAN Activity interrupt */ + UART4_IRQn = 35, /*!< UART4 Interrupt */ + SSP2_IRQn = 36, /*!< SSP2 Interrupt */ + LCD_IRQn = 37, /*!< LCD Interrupt */ + GPIO_IRQn = 38, /*!< GPIO Interrupt */ + PWM0_IRQn = 39, /*!< PWM0 Interrupt */ + EEPROM_IRQn = 40, /*!< EEPROM Interrupt */ +} IRQn_Type; + + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M3 Processor and Core Peripherals */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + +#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */ +//#include "system_LPC177x_8x.h" /* System Header */ + + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ + +#if defined ( __CC_ARM ) +#pragma anon_unions +#endif + +/*------------- System Control (SC) ------------------------------------------*/ +typedef struct +{ + __IO uint32_t FLASHCFG; /*!< Offset: 0x000 (R/W) Flash Accelerator Configuration Register */ + uint32_t RESERVED0[31]; + __IO uint32_t PLL0CON; /*!< Offset: 0x080 (R/W) PLL0 Control Register */ + __IO uint32_t PLL0CFG; /*!< Offset: 0x084 (R/W) PLL0 Configuration Register */ + __I uint32_t PLL0STAT; /*!< Offset: 0x088 (R/ ) PLL0 Status Register */ + __O uint32_t PLL0FEED; /*!< Offset: 0x08C ( /W) PLL0 Feed Register */ + uint32_t RESERVED1[4]; + __IO uint32_t PLL1CON; /*!< Offset: 0x0A0 (R/W) PLL1 Control Register */ + __IO uint32_t PLL1CFG; /*!< Offset: 0x0A4 (R/W) PLL1 Configuration Register */ + __I uint32_t PLL1STAT; /*!< Offset: 0x0A8 (R/ ) PLL1 Status Register */ + __O uint32_t PLL1FEED; /*!< Offset: 0x0AC ( /W) PLL1 Feed Register */ + uint32_t RESERVED2[4]; + __IO uint32_t PCON; /*!< Offset: 0x0C0 (R/W) Power Control Register */ + __IO uint32_t PCONP; /*!< Offset: 0x0C4 (R/W) Power Control for Peripherals Register */ + uint32_t RESERVED3[14]; + __IO uint32_t EMCCLKSEL; /*!< Offset: 0x100 (R/W) External Memory Controller Clock Selection Register */ + __IO uint32_t CCLKSEL; /*!< Offset: 0x104 (R/W) CPU Clock Selection Register */ + __IO uint32_t USBCLKSEL; /*!< Offset: 0x108 (R/W) USB Clock Selection Register */ + __IO uint32_t CLKSRCSEL; /*!< Offset: 0x10C (R/W) Clock Source Select Register */ + __IO uint32_t CANSLEEPCLR; /*!< Offset: 0x110 (R/W) CAN Sleep Clear Register */ + __IO uint32_t CANWAKEFLAGS; /*!< Offset: 0x114 (R/W) CAN Wake-up Flags Register */ + uint32_t RESERVED4[10]; + __IO uint32_t EXTINT; /*!< Offset: 0x140 (R/W) External Interrupt Flag Register */ + uint32_t RESERVED5[1]; + __IO uint32_t EXTMODE; /*!< Offset: 0x148 (R/W) External Interrupt Mode Register */ + __IO uint32_t EXTPOLAR; /*!< Offset: 0x14C (R/W) External Interrupt Polarity Register */ + uint32_t RESERVED6[12]; + __IO uint32_t RSID; /*!< Offset: 0x180 (R/W) Reset Source Identification Register */ + uint32_t RESERVED7[7]; + __IO uint32_t SCS; /*!< Offset: 0x1A0 (R/W) System Controls and Status Register */ + __IO uint32_t IRCTRIM; /*!< Offset: 0x1A4 (R/W) Clock Dividers */ + __IO uint32_t PCLKSEL; /*!< Offset: 0x1A8 (R/W) Peripheral Clock Selection Register */ + uint32_t RESERVED8; + __IO uint32_t PBOOST; /*!< Offset: 0x1B0 (R/W) Power Boost control register */ + uint32_t RESERVED9; + __IO uint32_t LCD_CFG; /*!< Offset: 0x1B8 (R/W) LCD Configuration and clocking control Register */ + uint32_t RESERVED10[1]; + __IO uint32_t USBIntSt; /*!< Offset: 0x1C0 (R/W) USB Interrupt Status Register */ + __IO uint32_t DMAREQSEL; /*!< Offset: 0x1C4 (R/W) DMA Request Select Register */ + __IO uint32_t CLKOUTCFG; /*!< Offset: 0x1C8 (R/W) Clock Output Configuration Register */ + __IO uint32_t RSTCON0; /*!< Offset: 0x1CC (R/W) RESET Control0 Register */ + __IO uint32_t RSTCON1; /*!< Offset: 0x1D0 (R/W) RESET Control1 Register */ + uint32_t RESERVED11[2]; + __IO uint32_t EMCDLYCTL; /*!< Offset: 0x1DC (R/W) SDRAM programmable delays */ + __IO uint32_t EMCCAL; /*!< Offset: 0x1E0 (R/W) Calibration of programmable delays */ + } LPC_SC_TypeDef; + +/*------------- Pin Connect Block (PINCON) -----------------------------------*/ +typedef struct +{ + __IO uint32_t P0_0; /* 0x000 */ + __IO uint32_t P0_1; + __IO uint32_t P0_2; + __IO uint32_t P0_3; + __IO uint32_t P0_4; + __IO uint32_t P0_5; + __IO uint32_t P0_6; + __IO uint32_t P0_7; + + __IO uint32_t P0_8; /* 0x020 */ + __IO uint32_t P0_9; + __IO uint32_t P0_10; + __IO uint32_t P0_11; + __IO uint32_t P0_12; + __IO uint32_t P0_13; + __IO uint32_t P0_14; + __IO uint32_t P0_15; + + __IO uint32_t P0_16; /* 0x040 */ + __IO uint32_t P0_17; + __IO uint32_t P0_18; + __IO uint32_t P0_19; + __IO uint32_t P0_20; + __IO uint32_t P0_21; + __IO uint32_t P0_22; + __IO uint32_t P0_23; + + __IO uint32_t P0_24; /* 0x060 */ + __IO uint32_t P0_25; + __IO uint32_t P0_26; + __IO uint32_t P0_27; + __IO uint32_t P0_28; + __IO uint32_t P0_29; + __IO uint32_t P0_30; + __IO uint32_t P0_31; + + __IO uint32_t P1_0; /* 0x080 */ + __IO uint32_t P1_1; + __IO uint32_t P1_2; + __IO uint32_t P1_3; + __IO uint32_t P1_4; + __IO uint32_t P1_5; + __IO uint32_t P1_6; + __IO uint32_t P1_7; + + __IO uint32_t P1_8; /* 0x0A0 */ + __IO uint32_t P1_9; + __IO uint32_t P1_10; + __IO uint32_t P1_11; + __IO uint32_t P1_12; + __IO uint32_t P1_13; + __IO uint32_t P1_14; + __IO uint32_t P1_15; + + __IO uint32_t P1_16; /* 0x0C0 */ + __IO uint32_t P1_17; + __IO uint32_t P1_18; + __IO uint32_t P1_19; + __IO uint32_t P1_20; + __IO uint32_t P1_21; + __IO uint32_t P1_22; + __IO uint32_t P1_23; + + __IO uint32_t P1_24; /* 0x0E0 */ + __IO uint32_t P1_25; + __IO uint32_t P1_26; + __IO uint32_t P1_27; + __IO uint32_t P1_28; + __IO uint32_t P1_29; + __IO uint32_t P1_30; + __IO uint32_t P1_31; + + __IO uint32_t P2_0; /* 0x100 */ + __IO uint32_t P2_1; + __IO uint32_t P2_2; + __IO uint32_t P2_3; + __IO uint32_t P2_4; + __IO uint32_t P2_5; + __IO uint32_t P2_6; + __IO uint32_t P2_7; + + __IO uint32_t P2_8; /* 0x120 */ + __IO uint32_t P2_9; + __IO uint32_t P2_10; + __IO uint32_t P2_11; + __IO uint32_t P2_12; + __IO uint32_t P2_13; + __IO uint32_t P2_14; + __IO uint32_t P2_15; + + __IO uint32_t P2_16; /* 0x140 */ + __IO uint32_t P2_17; + __IO uint32_t P2_18; + __IO uint32_t P2_19; + __IO uint32_t P2_20; + __IO uint32_t P2_21; + __IO uint32_t P2_22; + __IO uint32_t P2_23; + + __IO uint32_t P2_24; /* 0x160 */ + __IO uint32_t P2_25; + __IO uint32_t P2_26; + __IO uint32_t P2_27; + __IO uint32_t P2_28; + __IO uint32_t P2_29; + __IO uint32_t P2_30; + __IO uint32_t P2_31; + + __IO uint32_t P3_0; /* 0x180 */ + __IO uint32_t P3_1; + __IO uint32_t P3_2; + __IO uint32_t P3_3; + __IO uint32_t P3_4; + __IO uint32_t P3_5; + __IO uint32_t P3_6; + __IO uint32_t P3_7; + + __IO uint32_t P3_8; /* 0x1A0 */ + __IO uint32_t P3_9; + __IO uint32_t P3_10; + __IO uint32_t P3_11; + __IO uint32_t P3_12; + __IO uint32_t P3_13; + __IO uint32_t P3_14; + __IO uint32_t P3_15; + + __IO uint32_t P3_16; /* 0x1C0 */ + __IO uint32_t P3_17; + __IO uint32_t P3_18; + __IO uint32_t P3_19; + __IO uint32_t P3_20; + __IO uint32_t P3_21; + __IO uint32_t P3_22; + __IO uint32_t P3_23; + + __IO uint32_t P3_24; /* 0x1E0 */ + __IO uint32_t P3_25; + __IO uint32_t P3_26; + __IO uint32_t P3_27; + __IO uint32_t P3_28; + __IO uint32_t P3_29; + __IO uint32_t P3_30; + __IO uint32_t P3_31; + + __IO uint32_t P4_0; /* 0x200 */ + __IO uint32_t P4_1; + __IO uint32_t P4_2; + __IO uint32_t P4_3; + __IO uint32_t P4_4; + __IO uint32_t P4_5; + __IO uint32_t P4_6; + __IO uint32_t P4_7; + + __IO uint32_t P4_8; /* 0x220 */ + __IO uint32_t P4_9; + __IO uint32_t P4_10; + __IO uint32_t P4_11; + __IO uint32_t P4_12; + __IO uint32_t P4_13; + __IO uint32_t P4_14; + __IO uint32_t P4_15; + + __IO uint32_t P4_16; /* 0x240 */ + __IO uint32_t P4_17; + __IO uint32_t P4_18; + __IO uint32_t P4_19; + __IO uint32_t P4_20; + __IO uint32_t P4_21; + __IO uint32_t P4_22; + __IO uint32_t P4_23; + + __IO uint32_t P4_24; /* 0x260 */ + __IO uint32_t P4_25; + __IO uint32_t P4_26; + __IO uint32_t P4_27; + __IO uint32_t P4_28; + __IO uint32_t P4_29; + __IO uint32_t P4_30; + __IO uint32_t P4_31; + + __IO uint32_t P5_0; /* 0x280 */ + __IO uint32_t P5_1; + __IO uint32_t P5_2; + __IO uint32_t P5_3; + __IO uint32_t P5_4; /* 0x290 */ +} LPC_IOCON_TypeDef; + +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +typedef struct +{ + __IO uint32_t DIR; + uint32_t RESERVED0[3]; + __IO uint32_t MASK; + __IO uint32_t PIN; + __IO uint32_t SET; + __O uint32_t CLR; +} LPC_GPIO_TypeDef; + +typedef struct +{ + __I uint32_t IntStatus; + __I uint32_t IO0IntStatR; + __I uint32_t IO0IntStatF; + __O uint32_t IO0IntClr; + __IO uint32_t IO0IntEnR; + __IO uint32_t IO0IntEnF; + uint32_t RESERVED0[3]; + __I uint32_t IO2IntStatR; + __I uint32_t IO2IntStatF; + __O uint32_t IO2IntClr; + __IO uint32_t IO2IntEnR; + __IO uint32_t IO2IntEnF; +} LPC_GPIOINT_TypeDef; + +/*------------- Timer (TIM) --------------------------------------------------*/ +typedef struct +{ + __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */ + __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */ + __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */ + __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */ + __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */ + __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */ + __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */ + __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */ + __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */ + __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */ + __I uint32_t CR1; /*!< Offset: 0x030 Capture Register 1 (R/ ) */ + uint32_t RESERVED0[2]; + __IO uint32_t EMR; /*!< Offset: 0x03C External Match Register (R/W) */ + uint32_t RESERVED1[12]; + __IO uint32_t CTCR; /*!< Offset: 0x070 Count Control Register (R/W) */ +} LPC_TIM_TypeDef; + +/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/ +typedef struct +{ + __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */ + __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */ + __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */ + __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */ + __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */ + __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */ + __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */ + __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */ + __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */ + __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */ + __I uint32_t CR1; /*!< Offset: 0x030 Capture Register 1 (R/ ) */ + __I uint32_t CR2; /*!< Offset: 0x034 Capture Register 2 (R/ ) */ + __I uint32_t CR3; /*!< Offset: 0x038 Capture Register 3 (R/ ) */ + uint32_t RESERVED0; + __IO uint32_t MR4; /*!< Offset: 0x040 Match Register 4 (R/W) */ + __IO uint32_t MR5; /*!< Offset: 0x044 Match Register 5 (R/W) */ + __IO uint32_t MR6; /*!< Offset: 0x048 Match Register 6 (R/W) */ + __IO uint32_t PCR; /*!< Offset: 0x04C PWM Control Register (R/W) */ + __IO uint32_t LER; /*!< Offset: 0x050 Load Enable Register (R/W) */ + uint32_t RESERVED1[7]; + __IO uint32_t CTCR; /*!< Offset: 0x070 Counter Control Register (R/W) */ +} LPC_PWM_TypeDef; + +/*------------- Universal Asynchronous Receiver Transmitter (UARTx) -----------*/ +/* There are three types of UARTs on the chip: +(1) UART0,UART2, and UART3 are the standard UART. +(2) UART1 is the standard with modem capability. +(3) USART(UART4) is the sync/async UART with smart card capability. +More details can be found on the Users Manual. */ + +#if 0 +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[7]; + __I uint8_t LSR; + uint8_t RESERVED2[7]; + __IO uint8_t SCR; + uint8_t RESERVED3[3]; + __IO uint32_t ACR; + __IO uint8_t ICR; + uint8_t RESERVED4[3]; + __IO uint8_t FDR; + uint8_t RESERVED5[7]; + __IO uint8_t TER; + uint8_t RESERVED6[39]; + __I uint8_t FIFOLVL; +} LPC_UART_TypeDef; +#else +typedef struct +{ + union + { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union + { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union + { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[7];//Reserved + __I uint8_t LSR; + uint8_t RESERVED2[7];//Reserved + __IO uint8_t SCR; + uint8_t RESERVED3[3];//Reserved + __IO uint32_t ACR; + uint8_t RESERVED4[4];//Reserved + __IO uint8_t FDR; + uint8_t RESERVED5[7];//Reserved + __IO uint8_t TER; + uint8_t RESERVED8[27];//Reserved + __IO uint8_t RS485CTRL; + uint8_t RESERVED9[3];//Reserved + __IO uint8_t ADRMATCH; + uint8_t RESERVED10[3];//Reserved + __IO uint8_t RS485DLY; + uint8_t RESERVED11[3];//Reserved +}LPC_UART_TypeDef; +#endif + + +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[3]; + __IO uint8_t MCR; + uint8_t RESERVED2[3]; + __I uint8_t LSR; + uint8_t RESERVED3[3]; + __I uint8_t MSR; + uint8_t RESERVED4[3]; + __IO uint8_t SCR; + uint8_t RESERVED5[3]; + __IO uint32_t ACR; + uint32_t RESERVED6; + __IO uint32_t FDR; + uint32_t RESERVED7; + __IO uint8_t TER; + uint8_t RESERVED8[27]; + __IO uint8_t RS485CTRL; + uint8_t RESERVED9[3]; + __IO uint8_t ADRMATCH; + uint8_t RESERVED10[3]; + __IO uint8_t RS485DLY; + uint8_t RESERVED11[3]; +} LPC_UART1_TypeDef; + +typedef struct +{ + union { + __I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */ + __O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */ + __IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */ + }; + union { + __IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */ + __IO uint32_t IER; /*!< Offset: 0x000 Interrupt Enable Register (R/W) */ + }; + union { + __I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */ + __O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */ + }; + __IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x010 Modem control Register (R/W) */ + __I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */ + __I uint32_t MSR; /*!< Offset: 0x018 Modem status Register (R/ ) */ + __IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */ + __IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */ + __IO uint32_t ICR; /*!< Offset: 0x024 irDA Control Register (R/W) */ + __IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */ + __IO uint32_t OSR; /*!< Offset: 0x02C Over sampling Register (R/W) */ + uint32_t RESERVED0[6]; + __IO uint32_t SCI_CTRL; /*!< Offset: 0x048 Smart card Interface Control Register (R/W) */ + __IO uint32_t RS485CTRL; /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */ + __IO uint32_t ADRMATCH; /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */ + __IO uint32_t RS485DLY; /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */ + __IO uint32_t SYNCCTRL; /*!< Offset: 0x058 Synchronous Mode Control Register (R/W ) */ + __IO uint32_t TER; /*!< Offset: 0x05C Transmit Enable Register (R/W) */ +} LPC_UART4_TypeDef; + +/*------------- Synchronous Serial Communication (SSP) -----------------------*/ +typedef struct +{ + __IO uint32_t CR0; /*!< Offset: 0x000 Control Register 0 (R/W) */ + __IO uint32_t CR1; /*!< Offset: 0x004 Control Register 1 (R/W) */ + __IO uint32_t DR; /*!< Offset: 0x008 Data Register (R/W) */ + __I uint32_t SR; /*!< Offset: 0x00C Status Registe (R/ ) */ + __IO uint32_t CPSR; /*!< Offset: 0x010 Clock Prescale Register (R/W) */ + __IO uint32_t IMSC; /*!< Offset: 0x014 Interrupt Mask Set and Clear Register (R/W) */ + __IO uint32_t RIS; /*!< Offset: 0x018 Raw Interrupt Status Register (R/W) */ + __IO uint32_t MIS; /*!< Offset: 0x01C Masked Interrupt Status Register (R/W) */ + __IO uint32_t ICR; /*!< Offset: 0x020 SSPICR Interrupt Clear Register (R/W) */ + __IO uint32_t DMACR; +} LPC_SSP_TypeDef; + +/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/ +typedef struct +{ + __IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x004 I2C Status Register (R/ ) */ + __IO uint32_t DAT; /*!< Offset: 0x008 I2C Data Register (R/W) */ + __IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */ + __IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */ + __IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */ + __O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */ + __IO uint32_t MMCTRL; /*!< Offset: 0x01C Monitor mode control register (R/W) */ + __IO uint32_t ADR1; /*!< Offset: 0x020 I2C Slave Address Register 1 (R/W) */ + __IO uint32_t ADR2; /*!< Offset: 0x024 I2C Slave Address Register 2 (R/W) */ + __IO uint32_t ADR3; /*!< Offset: 0x028 I2C Slave Address Register 3 (R/W) */ + __I uint32_t DATA_BUFFER; /*!< Offset: 0x02C Data buffer register ( /W) */ + __IO uint32_t MASK0; /*!< Offset: 0x030 I2C Slave address mask register 0 (R/W) */ + __IO uint32_t MASK1; /*!< Offset: 0x034 I2C Slave address mask register 1 (R/W) */ + __IO uint32_t MASK2; /*!< Offset: 0x038 I2C Slave address mask register 2 (R/W) */ + __IO uint32_t MASK3; /*!< Offset: 0x03C I2C Slave address mask register 3 (R/W) */ +} LPC_I2C_TypeDef; + +/*------------- Inter IC Sound (I2S) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t DAO; + __IO uint32_t DAI; + __O uint32_t TXFIFO; + __I uint32_t RXFIFO; + __I uint32_t STATE; + __IO uint32_t DMA1; + __IO uint32_t DMA2; + __IO uint32_t IRQ; + __IO uint32_t TXRATE; + __IO uint32_t RXRATE; + __IO uint32_t TXBITRATE; + __IO uint32_t RXBITRATE; + __IO uint32_t TXMODE; + __IO uint32_t RXMODE; +} LPC_I2S_TypeDef; + +/*------------- Real-Time Clock (RTC) ----------------------------------------*/ +typedef struct +{ + __IO uint8_t ILR; + uint8_t RESERVED0[7]; + __IO uint8_t CCR; + uint8_t RESERVED1[3]; + __IO uint8_t CIIR; + uint8_t RESERVED2[3]; + __IO uint8_t AMR; + uint8_t RESERVED3[3]; + __I uint32_t CTIME0; + __I uint32_t CTIME1; + __I uint32_t CTIME2; + __IO uint8_t SEC; + uint8_t RESERVED4[3]; + __IO uint8_t MIN; + uint8_t RESERVED5[3]; + __IO uint8_t HOUR; + uint8_t RESERVED6[3]; + __IO uint8_t DOM; + uint8_t RESERVED7[3]; + __IO uint8_t DOW; + uint8_t RESERVED8[3]; + __IO uint16_t DOY; + uint16_t RESERVED9; + __IO uint8_t MONTH; + uint8_t RESERVED10[3]; + __IO uint16_t YEAR; + uint16_t RESERVED11; + __IO uint32_t CALIBRATION; + __IO uint32_t GPREG0; + __IO uint32_t GPREG1; + __IO uint32_t GPREG2; + __IO uint32_t GPREG3; + __IO uint32_t GPREG4; + __IO uint8_t RTC_AUXEN; + uint8_t RESERVED12[3]; + __IO uint8_t RTC_AUX; + uint8_t RESERVED13[3]; + __IO uint8_t ALSEC; + uint8_t RESERVED14[3]; + __IO uint8_t ALMIN; + uint8_t RESERVED15[3]; + __IO uint8_t ALHOUR; + uint8_t RESERVED16[3]; + __IO uint8_t ALDOM; + uint8_t RESERVED17[3]; + __IO uint8_t ALDOW; + uint8_t RESERVED18[3]; + __IO uint16_t ALDOY; + uint16_t RESERVED19; + __IO uint8_t ALMON; + uint8_t RESERVED20[3]; + __IO uint16_t ALYEAR; + uint16_t RESERVED21; + __IO uint32_t ERSTATUS; + __IO uint32_t ERCONTROL; + __IO uint32_t ERCOUNTERS; + uint32_t RESERVED22; + __IO uint32_t ERFIRSTSTAMP0; + __IO uint32_t ERFIRSTSTAMP1; + __IO uint32_t ERFIRSTSTAMP2; + uint32_t RESERVED23; + __IO uint32_t ERLASTSTAMP0; + __IO uint32_t ERLASTSTAMP1; + __IO uint32_t ERLASTSTAMP2; +} LPC_RTC_TypeDef; + +/*------------- Watchdog Timer (WDT) -----------------------------------------*/ +typedef struct +{ + __IO uint8_t MOD; + uint8_t RESERVED0[3]; + __IO uint32_t TC; + __O uint8_t FEED; + uint8_t RESERVED1[3]; + __I uint32_t TV; + uint32_t RESERVED2; + __IO uint32_t WARNINT; + __IO uint32_t WINDOW; +} LPC_WDT_TypeDef; + +/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/ +typedef struct +{ + __IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */ + __IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */ + uint32_t RESERVED0; + __IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */ + __IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */ + __IO uint32_t ADTRM; +} LPC_ADC_TypeDef; + +/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/ +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CTRL; + __IO uint32_t CNTVAL; +} LPC_DAC_TypeDef; + +/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/ +typedef struct +{ + __I uint32_t CON; + __O uint32_t CON_SET; + __O uint32_t CON_CLR; + __I uint32_t CAPCON; + __O uint32_t CAPCON_SET; + __O uint32_t CAPCON_CLR; + __IO uint32_t TC0; + __IO uint32_t TC1; + __IO uint32_t TC2; + __IO uint32_t LIM0; + __IO uint32_t LIM1; + __IO uint32_t LIM2; + __IO uint32_t MAT0; + __IO uint32_t MAT1; + __IO uint32_t MAT2; + __IO uint32_t DT; + __IO uint32_t CP; + __IO uint32_t CAP0; + __IO uint32_t CAP1; + __IO uint32_t CAP2; + __I uint32_t INTEN; + __O uint32_t INTEN_SET; + __O uint32_t INTEN_CLR; + __I uint32_t CNTCON; + __O uint32_t CNTCON_SET; + __O uint32_t CNTCON_CLR; + __I uint32_t INTF; + __O uint32_t INTF_SET; + __O uint32_t INTF_CLR; + __O uint32_t CAP_CLR; +} LPC_MCPWM_TypeDef; + +/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/ +typedef struct +{ + __O uint32_t CON; + __I uint32_t STAT; + __IO uint32_t CONF; + __I uint32_t POS; + __IO uint32_t MAXPOS; + __IO uint32_t CMPOS0; + __IO uint32_t CMPOS1; + __IO uint32_t CMPOS2; + __I uint32_t INXCNT; + __IO uint32_t INXCMP0; + __IO uint32_t LOAD; + __I uint32_t TIME; + __I uint32_t VEL; + __I uint32_t CAP; + __IO uint32_t VELCOMP; + __IO uint32_t FILTERPHA; + __IO uint32_t FILTERPHB; + __IO uint32_t FILTERINX; + __IO uint32_t WINDOW; + __IO uint32_t INXCMP1; + __IO uint32_t INXCMP2; + uint32_t RESERVED0[993]; + __O uint32_t IEC; + __O uint32_t IES; + __I uint32_t INTSTAT; + __I uint32_t IE; + __O uint32_t CLR; + __O uint32_t SET; +} LPC_QEI_TypeDef; + +/*------------- SD/MMC card Interface (MCI)-----------------------------------*/ +typedef struct +{ + __IO uint32_t POWER; + __IO uint32_t CLOCK; + __IO uint32_t ARGUMENT; + __IO uint32_t COMMAND; + __I uint32_t RESP_CMD; + __I uint32_t RESP0; + __I uint32_t RESP1; + __I uint32_t RESP2; + __I uint32_t RESP3; + __IO uint32_t DATATMR; + __IO uint32_t DATALEN; + __IO uint32_t DATACTRL; + __I uint32_t DATACNT; + __I uint32_t STATUS; + __O uint32_t CLEAR; + __IO uint32_t MASK0; + uint32_t RESERVED0[2]; + __I uint32_t FIFOCNT; + uint32_t RESERVED1[13]; + __IO uint32_t FIFO[16]; +} LPC_MCI_TypeDef; + +/*------------- Controller Area Network (CAN) --------------------------------*/ +typedef struct +{ + __IO uint32_t mask[512]; /* ID Masks */ +} LPC_CANAF_RAM_TypeDef; + +typedef struct /* Acceptance Filter Registers */ +{ + ///Offset: 0x00000000 - Acceptance Filter Register + __IO uint32_t AFMR; + + ///Offset: 0x00000004 - Standard Frame Individual Start Address Register + __IO uint32_t SFF_sa; + + ///Offset: 0x00000008 - Standard Frame Group Start Address Register + __IO uint32_t SFF_GRP_sa; + + ///Offset: 0x0000000C - Extended Frame Start Address Register + __IO uint32_t EFF_sa; + + ///Offset: 0x00000010 - Extended Frame Group Start Address Register + __IO uint32_t EFF_GRP_sa; + + ///Offset: 0x00000014 - End of AF Tables register + __IO uint32_t ENDofTable; + + ///Offset: 0x00000018 - LUT Error Address register + __I uint32_t LUTerrAd; + + ///Offset: 0x0000001C - LUT Error Register + __I uint32_t LUTerr; + + ///Offset: 0x00000020 - CAN Central Transmit Status Register + __IO uint32_t FCANIE; + + ///Offset: 0x00000024 - FullCAN Interrupt and Capture registers 0 + __IO uint32_t FCANIC0; + + ///Offset: 0x00000028 - FullCAN Interrupt and Capture registers 1 + __IO uint32_t FCANIC1; +} LPC_CANAF_TypeDef; + +typedef struct /* Central Registers */ +{ + __I uint32_t TxSR; + __I uint32_t RxSR; + __I uint32_t MSR; +} LPC_CANCR_TypeDef; + +typedef struct /* Controller Registers */ +{ + ///Offset: 0x00000000 - Controls the operating mode of the CAN Controller + __IO uint32_t MOD; + + ///Offset: 0x00000004 - Command bits that affect the state + __O uint32_t CMR; + + ///Offset: 0x00000008 - Global Controller Status and Error Counters + __IO uint32_t GSR; + + ///Offset: 0x0000000C - Interrupt status, Arbitration Lost Capture, Error Code Capture + __I uint32_t ICR; + + ///Offset: 0x00000010 - Interrupt Enable Register + __IO uint32_t IER; + + ///Offset: 0x00000014 - Bus Timing Register + __IO uint32_t BTR; + + ///Offset: 0x00000018 - Error Warning Limit + __IO uint32_t EWL; + + ///Offset: 0x0000001C - Status Register + __I uint32_t SR; + + ///Offset: 0x00000020 - Receive frame status + __IO uint32_t RFS; + + ///Offset: 0x00000024 - Received Identifier + __IO uint32_t RID; + + ///Offset: 0x00000028 - Received data bytes 1-4 + __IO uint32_t RDA; + + ///Offset: 0x0000002C - Received data bytes 5-8 + __IO uint32_t RDB; + + ///Offset: 0x00000030 - Transmit frame info (Tx Buffer 1) + __IO uint32_t TFI1; + + ///Offset: 0x00000034 - Transmit Identifier (Tx Buffer 1) + __IO uint32_t TID1; + + ///Offset: 0x00000038 - Transmit data bytes 1-4 (Tx Buffer 1) + __IO uint32_t TDA1; + + ///Offset: 0x0000003C - Transmit data bytes 5-8 (Tx Buffer 1) + __IO uint32_t TDB1; + + ///Offset: 0x00000040 - Transmit frame info (Tx Buffer 2) + __IO uint32_t TFI2; + + ///Offset: 0x00000044 - Transmit Identifier (Tx Buffer 2) + __IO uint32_t TID2; + + ///Offset: 0x00000048 - Transmit data bytes 1-4 (Tx Buffer 2) + __IO uint32_t TDA2; + + ///Offset: 0x0000004C - Transmit data bytes 5-8 (Tx Buffer 2) + __IO uint32_t TDB2; + + ///Offset: 0x00000050 - Transmit frame info (Tx Buffer 3) + __IO uint32_t TFI3; + + ///Offset: 0x00000054 - Transmit Identifier (Tx Buffer 3) + __IO uint32_t TID3; + + ///Offset: 0x00000058 - Transmit data bytes 1-4 (Tx Buffer 3) + __IO uint32_t TDA3; + + ///Offset: 0x0000005C - Transmit data bytes 5-8 (Tx Buffer 3) + __IO uint32_t TDB3; +} LPC_CAN_TypeDef; + +/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/ +typedef struct /* Common Registers */ +{ + __I uint32_t IntStat; + __I uint32_t IntTCStat; + __O uint32_t IntTCClear; + __I uint32_t IntErrStat; + __O uint32_t IntErrClr; + __I uint32_t RawIntTCStat; + __I uint32_t RawIntErrStat; + __I uint32_t EnbldChns; + __IO uint32_t SoftBReq; + __IO uint32_t SoftSReq; + __IO uint32_t SoftLBReq; + __IO uint32_t SoftLSReq; + __IO uint32_t Config; + __IO uint32_t Sync; +} LPC_GPDMA_TypeDef; + +typedef struct /* Channel Registers */ +{ + __IO uint32_t CSrcAddr; + __IO uint32_t CDestAddr; + __IO uint32_t CLLI; + __IO uint32_t CControl; + __IO uint32_t CConfig; +} LPC_GPDMACH_TypeDef; + +/*------------- Universal Serial Bus (USB) -----------------------------------*/ +typedef struct +{ + __I uint32_t Revision; /* USB Host Registers */ + __IO uint32_t Control; + __IO uint32_t CommandStatus; + __IO uint32_t InterruptStatus; + __IO uint32_t InterruptEnable; + __IO uint32_t InterruptDisable; + __IO uint32_t HCCA; + __I uint32_t PeriodCurrentED; + __IO uint32_t ControlHeadED; + __IO uint32_t ControlCurrentED; + __IO uint32_t BulkHeadED; + __IO uint32_t BulkCurrentED; + __I uint32_t DoneHead; + __IO uint32_t FmInterval; + __I uint32_t FmRemaining; + __I uint32_t FmNumber; + __IO uint32_t PeriodicStart; + __IO uint32_t LSTreshold; + __IO uint32_t RhDescriptorA; + __IO uint32_t RhDescriptorB; + __IO uint32_t RhStatus; + __IO uint32_t RhPortStatus1; + __IO uint32_t RhPortStatus2; + uint32_t RESERVED0[40]; + __I uint32_t Module_ID; + + __I uint32_t IntSt; /* USB On-The-Go Registers */ + __IO uint32_t IntEn; + __O uint32_t IntSet; + __O uint32_t IntClr; + __IO uint32_t StCtrl; + __IO uint32_t Tmr; + uint32_t RESERVED1[58]; + + __I uint32_t DevIntSt; /* USB Device Interrupt Registers */ + __IO uint32_t DevIntEn; + __O uint32_t DevIntClr; + __O uint32_t DevIntSet; + + __O uint32_t CmdCode; /* USB Device SIE Command Registers */ + __I uint32_t CmdData; + + __I uint32_t RxData; /* USB Device Transfer Registers */ + __O uint32_t TxData; + __I uint32_t RxPLen; + __O uint32_t TxPLen; + __IO uint32_t Ctrl; + __O uint32_t DevIntPri; + + __I uint32_t EpIntSt; /* USB Device Endpoint Interrupt Regs */ + __IO uint32_t EpIntEn; + __O uint32_t EpIntClr; + __O uint32_t EpIntSet; + __O uint32_t EpIntPri; + + __IO uint32_t ReEp; /* USB Device Endpoint Realization Reg*/ + __O uint32_t EpInd; + __IO uint32_t MaxPSize; + + __I uint32_t DMARSt; /* USB Device DMA Registers */ + __O uint32_t DMARClr; + __O uint32_t DMARSet; + uint32_t RESERVED2[9]; + __IO uint32_t UDCAH; + __I uint32_t EpDMASt; + __O uint32_t EpDMAEn; + __O uint32_t EpDMADis; + __I uint32_t DMAIntSt; + __IO uint32_t DMAIntEn; + uint32_t RESERVED3[2]; + __I uint32_t EoTIntSt; + __O uint32_t EoTIntClr; + __O uint32_t EoTIntSet; + __I uint32_t NDDRIntSt; + __O uint32_t NDDRIntClr; + __O uint32_t NDDRIntSet; + __I uint32_t SysErrIntSt; + __O uint32_t SysErrIntClr; + __O uint32_t SysErrIntSet; + uint32_t RESERVED4[15]; + + union { + __I uint32_t I2C_RX; /* USB OTG I2C Registers */ + __O uint32_t I2C_TX; + }; + __IO uint32_t I2C_STS; + __IO uint32_t I2C_CTL; + __IO uint32_t I2C_CLKHI; + __O uint32_t I2C_CLKLO; + uint32_t RESERVED5[824]; + + union { + __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */ + __IO uint32_t OTGClkCtrl; + }; + union { + __I uint32_t USBClkSt; + __I uint32_t OTGClkSt; + }; +} LPC_USB_TypeDef; + +/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/ +typedef struct +{ + __IO uint32_t MAC1; /* MAC Registers */ + __IO uint32_t MAC2; + __IO uint32_t IPGT; + __IO uint32_t IPGR; + __IO uint32_t CLRT; + __IO uint32_t MAXF; + __IO uint32_t SUPP; + __IO uint32_t TEST; + __IO uint32_t MCFG; + __IO uint32_t MCMD; + __IO uint32_t MADR; + __O uint32_t MWTD; + __I uint32_t MRDD; + __I uint32_t MIND; + uint32_t RESERVED0[2]; + __IO uint32_t SA0; + __IO uint32_t SA1; + __IO uint32_t SA2; + uint32_t RESERVED1[45]; + __IO uint32_t Command; /* Control Registers */ + __I uint32_t Status; + __IO uint32_t RxDescriptor; + __IO uint32_t RxStatus; + __IO uint32_t RxDescriptorNumber; + __I uint32_t RxProduceIndex; + __IO uint32_t RxConsumeIndex; + __IO uint32_t TxDescriptor; + __IO uint32_t TxStatus; + __IO uint32_t TxDescriptorNumber; + __IO uint32_t TxProduceIndex; + __I uint32_t TxConsumeIndex; + uint32_t RESERVED2[10]; + __I uint32_t TSV0; + __I uint32_t TSV1; + __I uint32_t RSV; + uint32_t RESERVED3[3]; + __IO uint32_t FlowControlCounter; + __I uint32_t FlowControlStatus; + uint32_t RESERVED4[34]; + __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */ + __I uint32_t RxFilterWoLStatus; + __O uint32_t RxFilterWoLClear; + uint32_t RESERVED5; + __IO uint32_t HashFilterL; + __IO uint32_t HashFilterH; + uint32_t RESERVED6[882]; + __I uint32_t IntStatus; /* Module Control Registers */ + __IO uint32_t IntEnable; + __O uint32_t IntClear; + __O uint32_t IntSet; + uint32_t RESERVED7; + __IO uint32_t PowerDown; + uint32_t RESERVED8; + __IO uint32_t Module_ID; +} LPC_EMAC_TypeDef; + +/*------------- LCD controller (LCD) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t TIMH; /* LCD Registers */ + __IO uint32_t TIMV; + __IO uint32_t POL; + __IO uint32_t LE; + __IO uint32_t UPBASE; + __IO uint32_t LPBASE; + __IO uint32_t CTRL; + __IO uint32_t INTMSK; + __I uint32_t INTRAW; + __I uint32_t INTSTAT; + __O uint32_t INTCLR; + __I uint32_t UPCURR; + __I uint32_t LPCURR; + uint32_t RESERVED0[115]; + __IO uint32_t PAL[128]; + uint32_t RESERVED1[256]; + __IO uint32_t CRSR_IMG[256]; + __IO uint32_t CRSR_CTRL; + __IO uint32_t CRSR_CFG; + __IO uint32_t CRSR_PAL0; + __IO uint32_t CRSR_PAL1; + __IO uint32_t CRSR_XY; + __IO uint32_t CRSR_CLIP; + uint32_t RESERVED2[2]; + __IO uint32_t CRSR_INTMSK; + __O uint32_t CRSR_INTCLR; + __I uint32_t CRSR_INTRAW; + __I uint32_t CRSR_INTSTAT; +} LPC_LCD_TypeDef; + +/*------------- External Memory Controller (EMC) -----------------------------*/ +typedef struct +{ + __IO uint32_t Control; + __I uint32_t Status; + __IO uint32_t Config; + uint32_t RESERVED0[5]; + __IO uint32_t DynamicControl; + __IO uint32_t DynamicRefresh; + __IO uint32_t DynamicReadConfig; + uint32_t RESERVED1[1]; + __IO uint32_t DynamicRP; + __IO uint32_t DynamicRAS; + __IO uint32_t DynamicSREX; + __IO uint32_t DynamicAPR; + __IO uint32_t DynamicDAL; + __IO uint32_t DynamicWR; + __IO uint32_t DynamicRC; + __IO uint32_t DynamicRFC; + __IO uint32_t DynamicXSR; + __IO uint32_t DynamicRRD; + __IO uint32_t DynamicMRD; + uint32_t RESERVED2[9]; + __IO uint32_t StaticExtendedWait; + uint32_t RESERVED3[31]; + __IO uint32_t DynamicConfig0; + __IO uint32_t DynamicRasCas0; + uint32_t RESERVED4[6]; + __IO uint32_t DynamicConfig1; + __IO uint32_t DynamicRasCas1; + uint32_t RESERVED5[6]; + __IO uint32_t DynamicConfig2; + __IO uint32_t DynamicRasCas2; + uint32_t RESERVED6[6]; + __IO uint32_t DynamicConfig3; + __IO uint32_t DynamicRasCas3; + uint32_t RESERVED7[38]; + __IO uint32_t StaticConfig0; + __IO uint32_t StaticWaitWen0; + __IO uint32_t StaticWaitOen0; + __IO uint32_t StaticWaitRd0; + __IO uint32_t StaticWaitPage0; + __IO uint32_t StaticWaitWr0; + __IO uint32_t StaticWaitTurn0; + uint32_t RESERVED8[1]; + __IO uint32_t StaticConfig1; + __IO uint32_t StaticWaitWen1; + __IO uint32_t StaticWaitOen1; + __IO uint32_t StaticWaitRd1; + __IO uint32_t StaticWaitPage1; + __IO uint32_t StaticWaitWr1; + __IO uint32_t StaticWaitTurn1; + uint32_t RESERVED9[1]; + __IO uint32_t StaticConfig2; + __IO uint32_t StaticWaitWen2; + __IO uint32_t StaticWaitOen2; + __IO uint32_t StaticWaitRd2; + __IO uint32_t StaticWaitPage2; + __IO uint32_t StaticWaitWr2; + __IO uint32_t StaticWaitTurn2; + uint32_t RESERVED10[1]; + __IO uint32_t StaticConfig3; + __IO uint32_t StaticWaitWen3; + __IO uint32_t StaticWaitOen3; + __IO uint32_t StaticWaitRd3; + __IO uint32_t StaticWaitPage3; + __IO uint32_t StaticWaitWr3; + __IO uint32_t StaticWaitTurn3; +} LPC_EMC_TypeDef; + +/*------------- CRC Engine (CRC) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t MODE; + __IO uint32_t SEED; + union { + __I uint32_t SUM; + struct { + __O uint32_t DATA; + } WR_DATA_DWORD; + + struct { + __O uint16_t DATA; + uint16_t RESERVED; + }WR_DATA_WORD; + + struct { + __O uint8_t DATA; + uint8_t RESERVED[3]; + }WR_DATA_BYTE; + }; +} LPC_CRC_TypeDef; + +/*------------- EEPROM Controller (EEPROM) -----------------------------------*/ +typedef struct +{ + __IO uint32_t CMD; /* 0x0080 */ + __IO uint32_t ADDR; + __IO uint32_t WDATA; + __IO uint32_t RDATA; + __IO uint32_t WSTATE; /* 0x0090 */ + __IO uint32_t CLKDIV; + __IO uint32_t PWRDWN; /* 0x0098 */ + uint32_t RESERVED0[975]; + __IO uint32_t INT_CLR_ENABLE; /* 0x0FD8 */ + __IO uint32_t INT_SET_ENABLE; + __IO uint32_t INT_STATUS; /* 0x0FE0 */ + __IO uint32_t INT_ENABLE; + __IO uint32_t INT_CLR_STATUS; + __IO uint32_t INT_SET_STATUS; +} LPC_EEPROM_TypeDef; + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#endif + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/* Base addresses */ +#define LPC_FLASH_BASE (0x00000000UL) +#define LPC_RAM_BASE (0x10000000UL) +#define LPC_PERI_RAM_BASE (0x20000000UL) +#define LPC_APB0_BASE (0x40000000UL) +#define LPC_APB1_BASE (0x40080000UL) +#define LPC_AHBRAM1_BASE (0x20004000UL) +#define LPC_AHB_BASE (0x20080000UL) +#define LPC_CM3_BASE (0xE0000000UL) + +/* APB0 peripherals */ +#define LPC_WDT_BASE (LPC_APB0_BASE + 0x00000) +#define LPC_TIM0_BASE (LPC_APB0_BASE + 0x04000) +#define LPC_TIM1_BASE (LPC_APB0_BASE + 0x08000) +#define LPC_UART0_BASE (LPC_APB0_BASE + 0x0C000) +#define LPC_UART1_BASE (LPC_APB0_BASE + 0x10000) +#define LPC_PWM0_BASE (LPC_APB0_BASE + 0x14000) +#define LPC_PWM1_BASE (LPC_APB0_BASE + 0x18000) +#define LPC_I2C0_BASE (LPC_APB0_BASE + 0x1C000) +#define LPC_RTC_BASE (LPC_APB0_BASE + 0x24000) +#define LPC_GPIOINT_BASE (LPC_APB0_BASE + 0x28080) +#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x2C000) +#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x30000) +#define LPC_ADC_BASE (LPC_APB0_BASE + 0x34000) +#define LPC_CANAF_RAM_BASE (LPC_APB0_BASE + 0x38000) +#define LPC_CANAF_BASE (LPC_APB0_BASE + 0x3C000) +#define LPC_CANCR_BASE (LPC_APB0_BASE + 0x40000) +#define LPC_CAN1_BASE (LPC_APB0_BASE + 0x44000) +#define LPC_CAN2_BASE (LPC_APB0_BASE + 0x48000) +#define LPC_I2C1_BASE (LPC_APB0_BASE + 0x5C000) + +/* APB1 peripherals */ +#define LPC_SSP0_BASE (LPC_APB1_BASE + 0x08000) +#define LPC_DAC_BASE (LPC_APB1_BASE + 0x0C000) +#define LPC_TIM2_BASE (LPC_APB1_BASE + 0x10000) +#define LPC_TIM3_BASE (LPC_APB1_BASE + 0x14000) +#define LPC_UART2_BASE (LPC_APB1_BASE + 0x18000) +#define LPC_UART3_BASE (LPC_APB1_BASE + 0x1C000) +#define LPC_I2C2_BASE (LPC_APB1_BASE + 0x20000) +#define LPC_UART4_BASE (LPC_APB1_BASE + 0x24000) +#define LPC_I2S_BASE (LPC_APB1_BASE + 0x28000) +#define LPC_SSP2_BASE (LPC_APB1_BASE + 0x2C000) +#define LPC_MCPWM_BASE (LPC_APB1_BASE + 0x38000) +#define LPC_QEI_BASE (LPC_APB1_BASE + 0x3C000) +#define LPC_MCI_BASE (LPC_APB1_BASE + 0x40000) +#define LPC_SC_BASE (LPC_APB1_BASE + 0x7C000) + +/* AHB peripherals */ +#define LPC_GPDMA_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPDMACH0_BASE (LPC_AHB_BASE + 0x00100) +#define LPC_GPDMACH1_BASE (LPC_AHB_BASE + 0x00120) +#define LPC_GPDMACH2_BASE (LPC_AHB_BASE + 0x00140) +#define LPC_GPDMACH3_BASE (LPC_AHB_BASE + 0x00160) +#define LPC_GPDMACH4_BASE (LPC_AHB_BASE + 0x00180) +#define LPC_GPDMACH5_BASE (LPC_AHB_BASE + 0x001A0) +#define LPC_GPDMACH6_BASE (LPC_AHB_BASE + 0x001C0) +#define LPC_GPDMACH7_BASE (LPC_AHB_BASE + 0x001E0) +#define LPC_EMAC_BASE (LPC_AHB_BASE + 0x04000) +#define LPC_LCD_BASE (LPC_AHB_BASE + 0x08000) +#define LPC_USB_BASE (LPC_AHB_BASE + 0x0C000) +#define LPC_CRC_BASE (LPC_AHB_BASE + 0x10000) +#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x18000) +#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x18020) +#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x18040) +#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x18060) +#define LPC_GPIO4_BASE (LPC_AHB_BASE + 0x18080) +#define LPC_GPIO5_BASE (LPC_AHB_BASE + 0x180A0) +#define LPC_EMC_BASE (LPC_AHB_BASE + 0x1C000) + +#define LPC_EEPROM_BASE (LPC_FLASH_BASE+ 0x200080) + + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define LPC_SC ((LPC_SC_TypeDef *) LPC_SC_BASE ) +#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE ) +#define LPC_TIM0 ((LPC_TIM_TypeDef *) LPC_TIM0_BASE ) +#define LPC_TIM1 ((LPC_TIM_TypeDef *) LPC_TIM1_BASE ) +#define LPC_TIM2 ((LPC_TIM_TypeDef *) LPC_TIM2_BASE ) +#define LPC_TIM3 ((LPC_TIM_TypeDef *) LPC_TIM3_BASE ) +#define LPC_UART0 ((LPC_UART_TypeDef *) LPC_UART0_BASE ) +#define LPC_UART1 ((LPC_UART1_TypeDef *) LPC_UART1_BASE ) +#define LPC_UART2 ((LPC_UART_TypeDef *) LPC_UART2_BASE ) +#define LPC_UART3 ((LPC_UART_TypeDef *) LPC_UART3_BASE ) +#define LPC_UART4 ((LPC_UART4_TypeDef *) LPC_UART4_BASE ) +#define LPC_PWM0 ((LPC_PWM_TypeDef *) LPC_PWM0_BASE ) +#define LPC_PWM1 ((LPC_PWM_TypeDef *) LPC_PWM1_BASE ) +#define LPC_I2C0 ((LPC_I2C_TypeDef *) LPC_I2C0_BASE ) +#define LPC_I2C1 ((LPC_I2C_TypeDef *) LPC_I2C1_BASE ) +#define LPC_I2C2 ((LPC_I2C_TypeDef *) LPC_I2C2_BASE ) +#define LPC_I2S ((LPC_I2S_TypeDef *) LPC_I2S_BASE ) +#define LPC_RTC ((LPC_RTC_TypeDef *) LPC_RTC_BASE ) +#define LPC_GPIOINT ((LPC_GPIOINT_TypeDef *) LPC_GPIOINT_BASE ) +#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE ) +#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE ) +#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE ) +#define LPC_SSP2 ((LPC_SSP_TypeDef *) LPC_SSP2_BASE ) +#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE ) +#define LPC_DAC ((LPC_DAC_TypeDef *) LPC_DAC_BASE ) +#define LPC_CANAF_RAM ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE) +#define LPC_CANAF ((LPC_CANAF_TypeDef *) LPC_CANAF_BASE ) +#define LPC_CANCR ((LPC_CANCR_TypeDef *) LPC_CANCR_BASE ) +#define LPC_CAN1 ((LPC_CAN_TypeDef *) LPC_CAN1_BASE ) +#define LPC_CAN2 ((LPC_CAN_TypeDef *) LPC_CAN2_BASE ) +#define LPC_MCPWM ((LPC_MCPWM_TypeDef *) LPC_MCPWM_BASE ) +#define LPC_QEI ((LPC_QEI_TypeDef *) LPC_QEI_BASE ) +#define LPC_MCI ((LPC_MCI_TypeDef *) LPC_MCI_BASE ) +#define LPC_GPDMA ((LPC_GPDMA_TypeDef *) LPC_GPDMA_BASE ) +#define LPC_GPDMACH0 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH0_BASE ) +#define LPC_GPDMACH1 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH1_BASE ) +#define LPC_GPDMACH2 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH2_BASE ) +#define LPC_GPDMACH3 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH3_BASE ) +#define LPC_GPDMACH4 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH4_BASE ) +#define LPC_GPDMACH5 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH5_BASE ) +#define LPC_GPDMACH6 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH6_BASE ) +#define LPC_GPDMACH7 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH7_BASE ) +#define LPC_EMAC ((LPC_EMAC_TypeDef *) LPC_EMAC_BASE ) +#define LPC_LCD ((LPC_LCD_TypeDef *) LPC_LCD_BASE ) +#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE ) +#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE ) +#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE ) +#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE ) +#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE ) +#define LPC_GPIO4 ((LPC_GPIO_TypeDef *) LPC_GPIO4_BASE ) +#define LPC_GPIO5 ((LPC_GPIO_TypeDef *) LPC_GPIO5_BASE ) +#define LPC_EMC ((LPC_EMC_TypeDef *) LPC_EMC_BASE ) +#define LPC_CRC ((LPC_CRC_TypeDef *) LPC_CRC_BASE ) +#define LPC_EEPROM ((LPC_EEPROM_TypeDef *) LPC_EEPROM_BASE ) + +#endif // __LPC177x_8x_H__ diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC407x_8x_177x_8x.h b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC407x_8x_177x_8x.h new file mode 100644 index 0000000000000000000000000000000000000000..9942f382e5b56866d23a6cc58d4046f36560baee --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/LPC407x_8x_177x_8x.h @@ -0,0 +1,1514 @@ +/****************************************************************************************************//** +* $Id$ LPC407x_8x_177x_8x.h 2012-04-25 +*//** + * @file LPC407x_8x_177x_8x.h + * + * @brief CMSIS Cortex-M4 Cortex-M3 Peripheral Access Layer Header File for + * NXP LPC407x_8x_177x_8x. + * @version V0.7 + * @date 20. June 2012 + * @author NXP MCU SW Application Team +* +* Copyright(C) 2012, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 __LPC407x_8x_177x_8x_H__ +#define __LPC407x_8x_177x_8x_H__ + + + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/****** 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 */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC407x_8x_177x_8x Specific Interrupt Numbers *******************************************************/ + WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */ + TIMER0_IRQn = 1, /*!< Timer0 Interrupt */ + TIMER1_IRQn = 2, /*!< Timer1 Interrupt */ + TIMER2_IRQn = 3, /*!< Timer2 Interrupt */ + TIMER3_IRQn = 4, /*!< Timer3 Interrupt */ + UART0_IRQn = 5, /*!< UART0 Interrupt */ + UART1_IRQn = 6, /*!< UART1 Interrupt */ + UART2_IRQn = 7, /*!< UART2 Interrupt */ + UART3_IRQn = 8, /*!< UART3 Interrupt */ + PWM1_IRQn = 9, /*!< PWM1 Interrupt */ + I2C0_IRQn = 10, /*!< I2C0 Interrupt */ + I2C1_IRQn = 11, /*!< I2C1 Interrupt */ + I2C2_IRQn = 12, /*!< I2C2 Interrupt */ + Reserved0_IRQn = 13, /*!< Reserved */ + SSP0_IRQn = 14, /*!< SSP0 Interrupt */ + SSP1_IRQn = 15, /*!< SSP1 Interrupt */ + PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */ + RTC_IRQn = 17, /*!< Real Time Clock Interrupt */ + EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */ + EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */ + EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */ + EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */ + ADC_IRQn = 22, /*!< A/D Converter Interrupt */ + BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */ + USB_IRQn = 24, /*!< USB Interrupt */ + CAN_IRQn = 25, /*!< CAN Interrupt */ + DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */ + I2S_IRQn = 27, /*!< I2S Interrupt */ + ENET_IRQn = 28, /*!< Ethernet Interrupt */ + MCI_IRQn = 29, /*!< SD/MMC card I/F Interrupt */ + MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */ + QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */ + PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */ + USBActivity_IRQn = 33, /*!< USB Activity interrupt */ + CANActivity_IRQn = 34, /*!< CAN Activity interrupt */ + UART4_IRQn = 35, /*!< UART4 Interrupt */ + SSP2_IRQn = 36, /*!< SSP2 Interrupt */ + LCD_IRQn = 37, /*!< LCD Interrupt */ + GPIO_IRQn = 38, /*!< GPIO Interrupt */ + PWM0_IRQn = 39, /*!< 39 PWM0 */ + EEPROM_IRQn = 40, /*!< 40 EEPROM */ + CMP0_IRQn = 41, /*!< 41 CMP0 */ + CMP1_IRQn = 42 /*!< 42 CMP1 */ +} IRQn_Type; + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ +#ifdef CORE_M4 +/* ----------------Configuration of the cm4 Processor and Core Peripherals---------------- */ +#define __CM4_REV 0x0000 /*!< Cortex-M4 Core Revision */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present or not */ + + +#include "core_cm4.h" /*!< Cortex-M4 processor and core peripherals */ +#else +/* Configuration of the Cortex-M3 Processor and Core Peripherals */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + +#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */ + +#endif + +#include "system_LPC407x_8x_177x_8x.h" /*!< LPC408x_7x System */ + + + + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +#if defined ( __CC_ARM ) +#pragma anon_unions +#elif defined ( __ICCARM__ ) +#pragma language=save +#pragma language=extended +#endif + +/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/ +typedef struct /* Common Registers */ +{ + __I uint32_t IntStat; + __I uint32_t IntTCStat; + __O uint32_t IntTCClear; + __I uint32_t IntErrStat; + __O uint32_t IntErrClr; + __I uint32_t RawIntTCStat; + __I uint32_t RawIntErrStat; + __I uint32_t EnbldChns; + __IO uint32_t SoftBReq; + __IO uint32_t SoftSReq; + __IO uint32_t SoftLBReq; + __IO uint32_t SoftLSReq; + __IO uint32_t Config; + __IO uint32_t Sync; +} LPC_GPDMA_TypeDef; + +typedef struct /* Channel Registers */ +{ + __IO uint32_t CSrcAddr; + __IO uint32_t CDestAddr; + __IO uint32_t CLLI; + __IO uint32_t CControl; + __IO uint32_t CConfig; +} LPC_GPDMACH_TypeDef; + +/*------------- System Control (SC) ------------------------------------------*/ +typedef struct +{ + __IO uint32_t FLASHCFG; /*!< Offset: 0x000 (R/W) Flash Accelerator Configuration Register */ + uint32_t RESERVED0[31]; + __IO uint32_t PLL0CON; /*!< Offset: 0x080 (R/W) PLL0 Control Register */ + __IO uint32_t PLL0CFG; /*!< Offset: 0x084 (R/W) PLL0 Configuration Register */ + __I uint32_t PLL0STAT; /*!< Offset: 0x088 (R/ ) PLL0 Status Register */ + __O uint32_t PLL0FEED; /*!< Offset: 0x08C ( /W) PLL0 Feed Register */ + uint32_t RESERVED1[4]; + __IO uint32_t PLL1CON; /*!< Offset: 0x0A0 (R/W) PLL1 Control Register */ + __IO uint32_t PLL1CFG; /*!< Offset: 0x0A4 (R/W) PLL1 Configuration Register */ + __I uint32_t PLL1STAT; /*!< Offset: 0x0A8 (R/ ) PLL1 Status Register */ + __O uint32_t PLL1FEED; /*!< Offset: 0x0AC ( /W) PLL1 Feed Register */ + uint32_t RESERVED2[4]; + __IO uint32_t PCON; /*!< Offset: 0x0C0 (R/W) Power Control Register */ + __IO uint32_t PCONP; /*!< Offset: 0x0C4 (R/W) Power Control for Peripherals Register */ + __IO uint32_t PCONP1; /*!< Offset: 0x0C8 (R/W) Power Control for Peripherals Register */ + uint32_t RESERVED3[13]; + __IO uint32_t EMCCLKSEL; /*!< Offset: 0x100 (R/W) External Memory Controller Clock Selection Register */ + __IO uint32_t CCLKSEL; /*!< Offset: 0x104 (R/W) CPU Clock Selection Register */ + __IO uint32_t USBCLKSEL; /*!< Offset: 0x108 (R/W) USB Clock Selection Register */ + __IO uint32_t CLKSRCSEL; /*!< Offset: 0x10C (R/W) Clock Source Select Register */ + __IO uint32_t CANSLEEPCLR; /*!< Offset: 0x110 (R/W) CAN Sleep Clear Register */ + __IO uint32_t CANWAKEFLAGS; /*!< Offset: 0x114 (R/W) CAN Wake-up Flags Register */ + uint32_t RESERVED4[10]; + __IO uint32_t EXTINT; /*!< Offset: 0x140 (R/W) External Interrupt Flag Register */ + uint32_t RESERVED5[1]; + __IO uint32_t EXTMODE; /*!< Offset: 0x148 (R/W) External Interrupt Mode Register */ + __IO uint32_t EXTPOLAR; /*!< Offset: 0x14C (R/W) External Interrupt Polarity Register */ + uint32_t RESERVED6[12]; + __IO uint32_t RSID; /*!< Offset: 0x180 (R/W) Reset Source Identification Register */ + uint32_t RESERVED7[7]; + __IO uint32_t SCS; /*!< Offset: 0x1A0 (R/W) System Controls and Status Register */ + __IO uint32_t IRCTRIM; /*!< Offset: 0x1A4 (R/W) Clock Dividers */ + __IO uint32_t PCLKSEL; /*!< Offset: 0x1A8 (R/W) Peripheral Clock Selection Register */ + uint32_t RESERVED8; + __IO uint32_t PBOOST; /*!< Offset: 0x1B0 (R/W) Power Boost control register */ + __IO uint32_t SPIFICLKSEL; + __IO uint32_t LCD_CFG; /*!< Offset: 0x1B8 (R/W) LCD Configuration and clocking control Register */ + uint32_t RESERVED10[1]; + __IO uint32_t USBIntSt; /*!< Offset: 0x1C0 (R/W) USB Interrupt Status Register */ + __IO uint32_t DMAREQSEL; /*!< Offset: 0x1C4 (R/W) DMA Request Select Register */ + __IO uint32_t CLKOUTCFG; /*!< Offset: 0x1C8 (R/W) Clock Output Configuration Register */ + __IO uint32_t RSTCON0; /*!< Offset: 0x1CC (R/W) RESET Control0 Register */ + __IO uint32_t RSTCON1; /*!< Offset: 0x1D0 (R/W) RESET Control1 Register */ + uint32_t RESERVED11[2]; + __IO uint32_t EMCDLYCTL; /*!< Offset: 0x1DC (R/W) SDRAM programmable delays */ + __IO uint32_t EMCCAL; /*!< Offset: 0x1E0 (R/W) Calibration of programmable delays */ + } LPC_SC_TypeDef; +/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/ +typedef struct +{ + __IO uint32_t MAC1; /* MAC Registers */ + __IO uint32_t MAC2; + __IO uint32_t IPGT; + __IO uint32_t IPGR; + __IO uint32_t CLRT; + __IO uint32_t MAXF; + __IO uint32_t SUPP; + __IO uint32_t TEST; + __IO uint32_t MCFG; + __IO uint32_t MCMD; + __IO uint32_t MADR; + __O uint32_t MWTD; + __I uint32_t MRDD; + __I uint32_t MIND; + uint32_t RESERVED0[2]; + __IO uint32_t SA0; + __IO uint32_t SA1; + __IO uint32_t SA2; + uint32_t RESERVED1[45]; + __IO uint32_t Command; /* Control Registers */ + __I uint32_t Status; + __IO uint32_t RxDescriptor; + __IO uint32_t RxStatus; + __IO uint32_t RxDescriptorNumber; + __I uint32_t RxProduceIndex; + __IO uint32_t RxConsumeIndex; + __IO uint32_t TxDescriptor; + __IO uint32_t TxStatus; + __IO uint32_t TxDescriptorNumber; + __IO uint32_t TxProduceIndex; + __I uint32_t TxConsumeIndex; + uint32_t RESERVED2[10]; + __I uint32_t TSV0; + __I uint32_t TSV1; + __I uint32_t RSV; + uint32_t RESERVED3[3]; + __IO uint32_t FlowControlCounter; + __I uint32_t FlowControlStatus; + uint32_t RESERVED4[34]; + __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */ + __I uint32_t RxFilterWoLStatus; + __O uint32_t RxFilterWoLClear; + uint32_t RESERVED5; + __IO uint32_t HashFilterL; + __IO uint32_t HashFilterH; + uint32_t RESERVED6[882]; + __I uint32_t IntStatus; /* Module Control Registers */ + __IO uint32_t IntEnable; + __O uint32_t IntClear; + __O uint32_t IntSet; + uint32_t RESERVED7; + __IO uint32_t PowerDown; + uint32_t RESERVED8; + __IO uint32_t Module_ID; +} LPC_EMAC_TypeDef; + +/*------------- LCD controller (LCD) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t TIMH; /* LCD Registers */ + __IO uint32_t TIMV; + __IO uint32_t POL; + __IO uint32_t LE; + __IO uint32_t UPBASE; + __IO uint32_t LPBASE; + __IO uint32_t CTRL; + __IO uint32_t INTMSK; + __I uint32_t INTRAW; + __I uint32_t INTSTAT; + __O uint32_t INTCLR; + __I uint32_t UPCURR; + __I uint32_t LPCURR; + uint32_t RESERVED0[115]; + __IO uint32_t PAL[128]; + uint32_t RESERVED1[256]; + __IO uint32_t CRSR_IMG[256]; + __IO uint32_t CRSR_CTRL; + __IO uint32_t CRSR_CFG; + __IO uint32_t CRSR_PAL0; + __IO uint32_t CRSR_PAL1; + __IO uint32_t CRSR_XY; + __IO uint32_t CRSR_CLIP; + uint32_t RESERVED2[2]; + __IO uint32_t CRSR_INTMSK; + __O uint32_t CRSR_INTCLR; + __I uint32_t CRSR_INTRAW; + __I uint32_t CRSR_INTSTAT; +} LPC_LCD_TypeDef; + +/*------------- Universal Serial Bus (USB) -----------------------------------*/ +typedef struct +{ + __I uint32_t Revision; /* USB Host Registers */ + __IO uint32_t Control; + __IO uint32_t CommandStatus; + __IO uint32_t InterruptStatus; + __IO uint32_t InterruptEnable; + __IO uint32_t InterruptDisable; + __IO uint32_t HCCA; + __I uint32_t PeriodCurrentED; + __IO uint32_t ControlHeadED; + __IO uint32_t ControlCurrentED; + __IO uint32_t BulkHeadED; + __IO uint32_t BulkCurrentED; + __I uint32_t DoneHead; + __IO uint32_t FmInterval; + __I uint32_t FmRemaining; + __I uint32_t FmNumber; + __IO uint32_t PeriodicStart; + __IO uint32_t LSTreshold; + __IO uint32_t RhDescriptorA; + __IO uint32_t RhDescriptorB; + __IO uint32_t RhStatus; + __IO uint32_t RhPortStatus1; + __IO uint32_t RhPortStatus2; + uint32_t RESERVED0[40]; + __I uint32_t Module_ID; + + __I uint32_t IntSt; /* USB On-The-Go Registers */ + __IO uint32_t IntEn; + __O uint32_t IntSet; + __O uint32_t IntClr; + __IO uint32_t StCtrl; + __IO uint32_t Tmr; + uint32_t RESERVED1[58]; + + __I uint32_t DevIntSt; /* USB Device Interrupt Registers */ + __IO uint32_t DevIntEn; + __O uint32_t DevIntClr; + __O uint32_t DevIntSet; + + __O uint32_t CmdCode; /* USB Device SIE Command Registers */ + __I uint32_t CmdData; + + __I uint32_t RxData; /* USB Device Transfer Registers */ + __O uint32_t TxData; + __I uint32_t RxPLen; + __O uint32_t TxPLen; + __IO uint32_t Ctrl; + __O uint32_t DevIntPri; + + __I uint32_t EpIntSt; /* USB Device Endpoint Interrupt Regs */ + __IO uint32_t EpIntEn; + __O uint32_t EpIntClr; + __O uint32_t EpIntSet; + __O uint32_t EpIntPri; + + __IO uint32_t ReEp; /* USB Device Endpoint Realization Reg*/ + __O uint32_t EpInd; + __IO uint32_t MaxPSize; + + __I uint32_t DMARSt; /* USB Device DMA Registers */ + __O uint32_t DMARClr; + __O uint32_t DMARSet; + uint32_t RESERVED2[9]; + __IO uint32_t UDCAH; + __I uint32_t EpDMASt; + __O uint32_t EpDMAEn; + __O uint32_t EpDMADis; + __I uint32_t DMAIntSt; + __IO uint32_t DMAIntEn; + uint32_t RESERVED3[2]; + __I uint32_t EoTIntSt; + __O uint32_t EoTIntClr; + __O uint32_t EoTIntSet; + __I uint32_t NDDRIntSt; + __O uint32_t NDDRIntClr; + __O uint32_t NDDRIntSet; + __I uint32_t SysErrIntSt; + __O uint32_t SysErrIntClr; + __O uint32_t SysErrIntSet; + uint32_t RESERVED4[15]; + + union { + __I uint32_t I2C_RX; /* USB OTG I2C Registers */ + __O uint32_t I2C_TX; + }; + __IO uint32_t I2C_STS; + __IO uint32_t I2C_CTL; + __IO uint32_t I2C_CLKHI; + __O uint32_t I2C_CLKLO; + uint32_t RESERVED5[824]; + + union { + __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */ + __IO uint32_t OTGClkCtrl; + }; + union { + __I uint32_t USBClkSt; + __I uint32_t OTGClkSt; + }; +} LPC_USB_TypeDef; + +/*------------- CRC Engine (CRC) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t MODE; + __IO uint32_t SEED; + union { + __I uint32_t SUM; + struct { + __O uint32_t DATA; + } WR_DATA_DWORD; + + struct { + __O uint16_t DATA; + uint16_t RESERVED; + }WR_DATA_WORD; + + struct { + __O uint8_t DATA; + uint8_t RESERVED[3]; + }WR_DATA_BYTE; + }; +} LPC_CRC_TypeDef; +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +typedef struct +{ + __IO uint32_t DIR; + uint32_t RESERVED0[3]; + __IO uint32_t MASK; + __IO uint32_t PIN; + __IO uint32_t SET; + __O uint32_t CLR; +} LPC_GPIO_TypeDef; + +typedef struct +{ + __I uint32_t IntStatus; + __I uint32_t IO0IntStatR; + __I uint32_t IO0IntStatF; + __O uint32_t IO0IntClr; + __IO uint32_t IO0IntEnR; + __IO uint32_t IO0IntEnF; + uint32_t RESERVED0[3]; + __I uint32_t IO2IntStatR; + __I uint32_t IO2IntStatF; + __O uint32_t IO2IntClr; + __IO uint32_t IO2IntEnR; + __IO uint32_t IO2IntEnF; +} LPC_GPIOINT_TypeDef; + +/*------------- External Memory Controller (EMC) -----------------------------*/ +typedef struct +{ + __IO uint32_t Control; + __I uint32_t Status; + __IO uint32_t Config; + uint32_t RESERVED0[5]; + __IO uint32_t DynamicControl; + __IO uint32_t DynamicRefresh; + __IO uint32_t DynamicReadConfig; + uint32_t RESERVED1[1]; + __IO uint32_t DynamicRP; + __IO uint32_t DynamicRAS; + __IO uint32_t DynamicSREX; + __IO uint32_t DynamicAPR; + __IO uint32_t DynamicDAL; + __IO uint32_t DynamicWR; + __IO uint32_t DynamicRC; + __IO uint32_t DynamicRFC; + __IO uint32_t DynamicXSR; + __IO uint32_t DynamicRRD; + __IO uint32_t DynamicMRD; + uint32_t RESERVED2[9]; + __IO uint32_t StaticExtendedWait; + uint32_t RESERVED3[31]; + __IO uint32_t DynamicConfig0; + __IO uint32_t DynamicRasCas0; + uint32_t RESERVED4[6]; + __IO uint32_t DynamicConfig1; + __IO uint32_t DynamicRasCas1; + uint32_t RESERVED5[6]; + __IO uint32_t DynamicConfig2; + __IO uint32_t DynamicRasCas2; + uint32_t RESERVED6[6]; + __IO uint32_t DynamicConfig3; + __IO uint32_t DynamicRasCas3; + uint32_t RESERVED7[38]; + __IO uint32_t StaticConfig0; + __IO uint32_t StaticWaitWen0; + __IO uint32_t StaticWaitOen0; + __IO uint32_t StaticWaitRd0; + __IO uint32_t StaticWaitPage0; + __IO uint32_t StaticWaitWr0; + __IO uint32_t StaticWaitTurn0; + uint32_t RESERVED8[1]; + __IO uint32_t StaticConfig1; + __IO uint32_t StaticWaitWen1; + __IO uint32_t StaticWaitOen1; + __IO uint32_t StaticWaitRd1; + __IO uint32_t StaticWaitPage1; + __IO uint32_t StaticWaitWr1; + __IO uint32_t StaticWaitTurn1; + uint32_t RESERVED9[1]; + __IO uint32_t StaticConfig2; + __IO uint32_t StaticWaitWen2; + __IO uint32_t StaticWaitOen2; + __IO uint32_t StaticWaitRd2; + __IO uint32_t StaticWaitPage2; + __IO uint32_t StaticWaitWr2; + __IO uint32_t StaticWaitTurn2; + uint32_t RESERVED10[1]; + __IO uint32_t StaticConfig3; + __IO uint32_t StaticWaitWen3; + __IO uint32_t StaticWaitOen3; + __IO uint32_t StaticWaitRd3; + __IO uint32_t StaticWaitPage3; + __IO uint32_t StaticWaitWr3; + __IO uint32_t StaticWaitTurn3; +} LPC_EMC_TypeDef; + +/*------------- Watchdog Timer (WDT) -----------------------------------------*/ +typedef struct +{ + __IO uint8_t MOD; + uint8_t RESERVED0[3]; + __IO uint32_t TC; + __O uint8_t FEED; + uint8_t RESERVED1[3]; + __I uint32_t TV; + uint32_t RESERVED2; + __IO uint32_t WARNINT; + __IO uint32_t WINDOW; +} LPC_WDT_TypeDef; + +/*------------- Timer (TIM) --------------------------------------------------*/ +typedef struct +{ + __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */ + __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */ + __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */ + __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */ + __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */ + __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */ + __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */ + __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */ + __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */ + __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */ + __I uint32_t CR1; /*!< Offset: 0x030 Capture Register 1 (R/ ) */ + uint32_t RESERVED0[2]; + __IO uint32_t EMR; /*!< Offset: 0x03C External Match Register (R/W) */ + uint32_t RESERVED1[12]; + __IO uint32_t CTCR; /*!< Offset: 0x070 Count Control Register (R/W) */ +} LPC_TIM_TypeDef; + + +/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/ +typedef struct +{ + __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */ + __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */ + __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */ + __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */ + __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */ + __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */ + __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */ + __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */ + __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */ + __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */ + __I uint32_t CR1; /*!< Offset: 0x030 Capture Register 1 (R/ ) */ + __I uint32_t CR2; /*!< Offset: 0x034 Capture Register 2 (R/ ) */ + __I uint32_t CR3; /*!< Offset: 0x038 Capture Register 3 (R/ ) */ + uint32_t RESERVED0; + __IO uint32_t MR4; /*!< Offset: 0x040 Match Register 4 (R/W) */ + __IO uint32_t MR5; /*!< Offset: 0x044 Match Register 5 (R/W) */ + __IO uint32_t MR6; /*!< Offset: 0x048 Match Register 6 (R/W) */ + __IO uint32_t PCR; /*!< Offset: 0x04C PWM Control Register (R/W) */ + __IO uint32_t LER; /*!< Offset: 0x050 Load Enable Register (R/W) */ + uint32_t RESERVED1[7]; + __IO uint32_t CTCR; /*!< Offset: 0x070 Counter Control Register (R/W) */ +} LPC_PWM_TypeDef; + +/*------------- Universal Asynchronous Receiver Transmitter (UARTx) -----------*/ +/* There are three types of UARTs on the chip: +(1) UART0,UART2, and UART3 are the standard UART. +(2) UART1 is the standard with modem capability. +(3) USART(UART4) is the sync/async UART with smart card capability. +More details can be found on the Users Manual. */ + +#if 0 +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[7]; + __I uint8_t LSR; + uint8_t RESERVED2[7]; + __IO uint8_t SCR; + uint8_t RESERVED3[3]; + __IO uint32_t ACR; + __IO uint8_t ICR; + uint8_t RESERVED4[3]; + __IO uint8_t FDR; + uint8_t RESERVED5[7]; + __IO uint8_t TER; + uint8_t RESERVED6[39]; + __I uint8_t FIFOLVL; +} LPC_UART_TypeDef; +#else +typedef struct +{ + union + { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union + { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union + { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[7];//Reserved + __I uint8_t LSR; + uint8_t RESERVED2[7];//Reserved + __IO uint8_t SCR; + uint8_t RESERVED3[3];//Reserved + __IO uint32_t ACR; + __IO uint8_t ICR; + uint8_t RESERVED4[3];//Reserved + __IO uint8_t FDR; + uint8_t RESERVED5[7];//Reserved + __IO uint8_t TER; + uint8_t RESERVED8[27];//Reserved + __IO uint8_t RS485CTRL; + uint8_t RESERVED9[3];//Reserved + __IO uint8_t ADRMATCH; + uint8_t RESERVED10[3];//Reserved + __IO uint8_t RS485DLY; + uint8_t RESERVED11[3];//Reserved + __I uint8_t FIFOLVL; +}LPC_UART_TypeDef; +#endif + + +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[3]; + __IO uint8_t MCR; + uint8_t RESERVED2[3]; + __I uint8_t LSR; + uint8_t RESERVED3[3]; + __I uint8_t MSR; + uint8_t RESERVED4[3]; + __IO uint8_t SCR; + uint8_t RESERVED5[3]; + __IO uint32_t ACR; + uint32_t RESERVED6; + __IO uint32_t FDR; + uint32_t RESERVED7; + __IO uint8_t TER; + uint8_t RESERVED8[27]; + __IO uint8_t RS485CTRL; + uint8_t RESERVED9[3]; + __IO uint8_t ADRMATCH; + uint8_t RESERVED10[3]; + __IO uint8_t RS485DLY; + uint8_t RESERVED11[3]; + __I uint8_t FIFOLVL; +} LPC_UART1_TypeDef; + +typedef struct +{ + union { + __I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */ + __O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */ + __IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */ + }; + union { + __IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */ + __IO uint32_t IER; /*!< Offset: 0x000 Interrupt Enable Register (R/W) */ + }; + union { + __I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */ + __O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */ + }; + __IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x010 Modem control Register (R/W) */ + __I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */ + __I uint32_t MSR; /*!< Offset: 0x018 Modem status Register (R/ ) */ + __IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */ + __IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */ + __IO uint32_t ICR; /*!< Offset: 0x024 irDA Control Register (R/W) */ + __IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */ + __IO uint32_t OSR; /*!< Offset: 0x02C Over sampling Register (R/W) */ + __O uint32_t POP; /*!< Offset: 0x030 NHP Pop Register (W) */ + __IO uint32_t MODE; /*!< Offset: 0x034 NHP Mode selection Register (W) */ + uint32_t RESERVED0[2]; + __IO uint32_t HDEN; /*!< Offset: 0x040 Half duplex Enable Register (R/W) */ + uint32_t RESERVED1; + __IO uint32_t SCI_CTRL; /*!< Offset: 0x048 Smart card Interface Control Register (R/W) */ + __IO uint32_t RS485CTRL; /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */ + __IO uint32_t ADRMATCH; /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */ + __IO uint32_t RS485DLY; /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */ + __IO uint32_t SYNCCTRL; /*!< Offset: 0x058 Synchronous Mode Control Register (R/W ) */ + __IO uint32_t TER; /*!< Offset: 0x05C Transmit Enable Register (R/W) */ + uint32_t RESERVED2[989]; + __I uint32_t CFG; /*!< Offset: 0xFD4 Configuration Register (R) */ + __O uint32_t INTCE; /*!< Offset: 0xFD8 Interrupt Clear Enable Register (W) */ + __O uint32_t INTSE; /*!< Offset: 0xFDC Interrupt Set Enable Register (W) */ + __I uint32_t INTS; /*!< Offset: 0xFE0 Interrupt Status Register (R) */ + __I uint32_t INTE; /*!< Offset: 0xFE4 Interrupt Enable Register (R) */ + __O uint32_t INTCS; /*!< Offset: 0xFE8 Interrupt Clear Status Register (W) */ + __O uint32_t INTSS; /*!< Offset: 0xFEC Interrupt Set Status Register (W) */ + uint32_t RESERVED3[3]; + __I uint32_t MID; /*!< Offset: 0xFFC Module Identification Register (R) */ +} LPC_UART4_TypeDef; +/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/ +typedef struct +{ + __IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x004 I2C Status Register (R/ ) */ + __IO uint32_t DAT; /*!< Offset: 0x008 I2C Data Register (R/W) */ + __IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */ + __IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */ + __IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */ + __O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */ + __IO uint32_t MMCTRL; /*!< Offset: 0x01C Monitor mode control register (R/W) */ + __IO uint32_t ADR1; /*!< Offset: 0x020 I2C Slave Address Register 1 (R/W) */ + __IO uint32_t ADR2; /*!< Offset: 0x024 I2C Slave Address Register 2 (R/W) */ + __IO uint32_t ADR3; /*!< Offset: 0x028 I2C Slave Address Register 3 (R/W) */ + __I uint32_t DATA_BUFFER; /*!< Offset: 0x02C Data buffer register ( /W) */ + __IO uint32_t MASK0; /*!< Offset: 0x030 I2C Slave address mask register 0 (R/W) */ + __IO uint32_t MASK1; /*!< Offset: 0x034 I2C Slave address mask register 1 (R/W) */ + __IO uint32_t MASK2; /*!< Offset: 0x038 I2C Slave address mask register 2 (R/W) */ + __IO uint32_t MASK3; /*!< Offset: 0x03C I2C Slave address mask register 3 (R/W) */ +} LPC_I2C_TypeDef; + +/*------------- Real-Time Clock (RTC) ----------------------------------------*/ +typedef struct +{ + __IO uint8_t ILR; + uint8_t RESERVED0[7]; + __IO uint8_t CCR; + uint8_t RESERVED1[3]; + __IO uint8_t CIIR; + uint8_t RESERVED2[3]; + __IO uint8_t AMR; + uint8_t RESERVED3[3]; + __I uint32_t CTIME0; + __I uint32_t CTIME1; + __I uint32_t CTIME2; + __IO uint8_t SEC; + uint8_t RESERVED4[3]; + __IO uint8_t MIN; + uint8_t RESERVED5[3]; + __IO uint8_t HOUR; + uint8_t RESERVED6[3]; + __IO uint8_t DOM; + uint8_t RESERVED7[3]; + __IO uint8_t DOW; + uint8_t RESERVED8[3]; + __IO uint16_t DOY; + uint16_t RESERVED9; + __IO uint8_t MONTH; + uint8_t RESERVED10[3]; + __IO uint16_t YEAR; + uint16_t RESERVED11; + __IO uint32_t CALIBRATION; + __IO uint32_t GPREG0; + __IO uint32_t GPREG1; + __IO uint32_t GPREG2; + __IO uint32_t GPREG3; + __IO uint32_t GPREG4; + __IO uint8_t RTC_AUXEN; + uint8_t RESERVED12[3]; + __IO uint8_t RTC_AUX; + uint8_t RESERVED13[3]; + __IO uint8_t ALSEC; + uint8_t RESERVED14[3]; + __IO uint8_t ALMIN; + uint8_t RESERVED15[3]; + __IO uint8_t ALHOUR; + uint8_t RESERVED16[3]; + __IO uint8_t ALDOM; + uint8_t RESERVED17[3]; + __IO uint8_t ALDOW; + uint8_t RESERVED18[3]; + __IO uint16_t ALDOY; + uint16_t RESERVED19; + __IO uint8_t ALMON; + uint8_t RESERVED20[3]; + __IO uint16_t ALYEAR; + uint16_t RESERVED21; + __IO uint32_t ERSTATUS; + __IO uint32_t ERCONTROL; + __IO uint32_t ERCOUNTERS; + uint32_t RESERVED22; + __IO uint32_t ERFIRSTSTAMP0; + __IO uint32_t ERFIRSTSTAMP1; + __IO uint32_t ERFIRSTSTAMP2; + uint32_t RESERVED23; + __IO uint32_t ERLASTSTAMP0; + __IO uint32_t ERLASTSTAMP1; + __IO uint32_t ERLASTSTAMP2; +} LPC_RTC_TypeDef; + + + +/*------------- Pin Connect Block (PINCON) -----------------------------------*/ +typedef struct +{ + __IO uint32_t P0_0; /* 0x000 */ + __IO uint32_t P0_1; + __IO uint32_t P0_2; + __IO uint32_t P0_3; + __IO uint32_t P0_4; + __IO uint32_t P0_5; + __IO uint32_t P0_6; + __IO uint32_t P0_7; + + __IO uint32_t P0_8; /* 0x020 */ + __IO uint32_t P0_9; + __IO uint32_t P0_10; + __IO uint32_t P0_11; + __IO uint32_t P0_12; + __IO uint32_t P0_13; + __IO uint32_t P0_14; + __IO uint32_t P0_15; + + __IO uint32_t P0_16; /* 0x040 */ + __IO uint32_t P0_17; + __IO uint32_t P0_18; + __IO uint32_t P0_19; + __IO uint32_t P0_20; + __IO uint32_t P0_21; + __IO uint32_t P0_22; + __IO uint32_t P0_23; + + __IO uint32_t P0_24; /* 0x060 */ + __IO uint32_t P0_25; + __IO uint32_t P0_26; + __IO uint32_t P0_27; + __IO uint32_t P0_28; + __IO uint32_t P0_29; + __IO uint32_t P0_30; + __IO uint32_t P0_31; + + __IO uint32_t P1_0; /* 0x080 */ + __IO uint32_t P1_1; + __IO uint32_t P1_2; + __IO uint32_t P1_3; + __IO uint32_t P1_4; + __IO uint32_t P1_5; + __IO uint32_t P1_6; + __IO uint32_t P1_7; + + __IO uint32_t P1_8; /* 0x0A0 */ + __IO uint32_t P1_9; + __IO uint32_t P1_10; + __IO uint32_t P1_11; + __IO uint32_t P1_12; + __IO uint32_t P1_13; + __IO uint32_t P1_14; + __IO uint32_t P1_15; + + __IO uint32_t P1_16; /* 0x0C0 */ + __IO uint32_t P1_17; + __IO uint32_t P1_18; + __IO uint32_t P1_19; + __IO uint32_t P1_20; + __IO uint32_t P1_21; + __IO uint32_t P1_22; + __IO uint32_t P1_23; + + __IO uint32_t P1_24; /* 0x0E0 */ + __IO uint32_t P1_25; + __IO uint32_t P1_26; + __IO uint32_t P1_27; + __IO uint32_t P1_28; + __IO uint32_t P1_29; + __IO uint32_t P1_30; + __IO uint32_t P1_31; + + __IO uint32_t P2_0; /* 0x100 */ + __IO uint32_t P2_1; + __IO uint32_t P2_2; + __IO uint32_t P2_3; + __IO uint32_t P2_4; + __IO uint32_t P2_5; + __IO uint32_t P2_6; + __IO uint32_t P2_7; + + __IO uint32_t P2_8; /* 0x120 */ + __IO uint32_t P2_9; + __IO uint32_t P2_10; + __IO uint32_t P2_11; + __IO uint32_t P2_12; + __IO uint32_t P2_13; + __IO uint32_t P2_14; + __IO uint32_t P2_15; + + __IO uint32_t P2_16; /* 0x140 */ + __IO uint32_t P2_17; + __IO uint32_t P2_18; + __IO uint32_t P2_19; + __IO uint32_t P2_20; + __IO uint32_t P2_21; + __IO uint32_t P2_22; + __IO uint32_t P2_23; + + __IO uint32_t P2_24; /* 0x160 */ + __IO uint32_t P2_25; + __IO uint32_t P2_26; + __IO uint32_t P2_27; + __IO uint32_t P2_28; + __IO uint32_t P2_29; + __IO uint32_t P2_30; + __IO uint32_t P2_31; + + __IO uint32_t P3_0; /* 0x180 */ + __IO uint32_t P3_1; + __IO uint32_t P3_2; + __IO uint32_t P3_3; + __IO uint32_t P3_4; + __IO uint32_t P3_5; + __IO uint32_t P3_6; + __IO uint32_t P3_7; + + __IO uint32_t P3_8; /* 0x1A0 */ + __IO uint32_t P3_9; + __IO uint32_t P3_10; + __IO uint32_t P3_11; + __IO uint32_t P3_12; + __IO uint32_t P3_13; + __IO uint32_t P3_14; + __IO uint32_t P3_15; + + __IO uint32_t P3_16; /* 0x1C0 */ + __IO uint32_t P3_17; + __IO uint32_t P3_18; + __IO uint32_t P3_19; + __IO uint32_t P3_20; + __IO uint32_t P3_21; + __IO uint32_t P3_22; + __IO uint32_t P3_23; + + __IO uint32_t P3_24; /* 0x1E0 */ + __IO uint32_t P3_25; + __IO uint32_t P3_26; + __IO uint32_t P3_27; + __IO uint32_t P3_28; + __IO uint32_t P3_29; + __IO uint32_t P3_30; + __IO uint32_t P3_31; + + __IO uint32_t P4_0; /* 0x200 */ + __IO uint32_t P4_1; + __IO uint32_t P4_2; + __IO uint32_t P4_3; + __IO uint32_t P4_4; + __IO uint32_t P4_5; + __IO uint32_t P4_6; + __IO uint32_t P4_7; + + __IO uint32_t P4_8; /* 0x220 */ + __IO uint32_t P4_9; + __IO uint32_t P4_10; + __IO uint32_t P4_11; + __IO uint32_t P4_12; + __IO uint32_t P4_13; + __IO uint32_t P4_14; + __IO uint32_t P4_15; + + __IO uint32_t P4_16; /* 0x240 */ + __IO uint32_t P4_17; + __IO uint32_t P4_18; + __IO uint32_t P4_19; + __IO uint32_t P4_20; + __IO uint32_t P4_21; + __IO uint32_t P4_22; + __IO uint32_t P4_23; + + __IO uint32_t P4_24; /* 0x260 */ + __IO uint32_t P4_25; + __IO uint32_t P4_26; + __IO uint32_t P4_27; + __IO uint32_t P4_28; + __IO uint32_t P4_29; + __IO uint32_t P4_30; + __IO uint32_t P4_31; + + __IO uint32_t P5_0; /* 0x280 */ + __IO uint32_t P5_1; + __IO uint32_t P5_2; + __IO uint32_t P5_3; + __IO uint32_t P5_4; /* 0x290 */ +} LPC_IOCON_TypeDef; + + + + + + +/*------------- Synchronous Serial Communication (SSP) -----------------------*/ +typedef struct +{ + __IO uint32_t CR0; /*!< Offset: 0x000 Control Register 0 (R/W) */ + __IO uint32_t CR1; /*!< Offset: 0x004 Control Register 1 (R/W) */ + __IO uint32_t DR; /*!< Offset: 0x008 Data Register (R/W) */ + __I uint32_t SR; /*!< Offset: 0x00C Status Registe (R/ ) */ + __IO uint32_t CPSR; /*!< Offset: 0x010 Clock Prescale Register (R/W) */ + __IO uint32_t IMSC; /*!< Offset: 0x014 Interrupt Mask Set and Clear Register (R/W) */ + __IO uint32_t RIS; /*!< Offset: 0x018 Raw Interrupt Status Register (R/W) */ + __IO uint32_t MIS; /*!< Offset: 0x01C Masked Interrupt Status Register (R/W) */ + __IO uint32_t ICR; /*!< Offset: 0x020 SSPICR Interrupt Clear Register (R/W) */ + __IO uint32_t DMACR; +} LPC_SSP_TypeDef; + +/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/ +typedef struct +{ + __IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */ + __IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */ + uint32_t RESERVED0; + __IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */ + __IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */ + __IO uint32_t ADTRM; +} LPC_ADC_TypeDef; + +/*------------- Controller Area Network (CAN) --------------------------------*/ +typedef struct +{ + __IO uint32_t mask[512]; /* ID Masks */ +} LPC_CANAF_RAM_TypeDef; + +typedef struct /* Acceptance Filter Registers */ +{ + ///Offset: 0x00000000 - Acceptance Filter Register + __IO uint32_t AFMR; + + ///Offset: 0x00000004 - Standard Frame Individual Start Address Register + __IO uint32_t SFF_sa; + + ///Offset: 0x00000008 - Standard Frame Group Start Address Register + __IO uint32_t SFF_GRP_sa; + + ///Offset: 0x0000000C - Extended Frame Start Address Register + __IO uint32_t EFF_sa; + + ///Offset: 0x00000010 - Extended Frame Group Start Address Register + __IO uint32_t EFF_GRP_sa; + + ///Offset: 0x00000014 - End of AF Tables register + __IO uint32_t ENDofTable; + + ///Offset: 0x00000018 - LUT Error Address register + __I uint32_t LUTerrAd; + + ///Offset: 0x0000001C - LUT Error Register + __I uint32_t LUTerr; + + ///Offset: 0x00000020 - CAN Central Transmit Status Register + __IO uint32_t FCANIE; + + ///Offset: 0x00000024 - FullCAN Interrupt and Capture registers 0 + __IO uint32_t FCANIC0; + + ///Offset: 0x00000028 - FullCAN Interrupt and Capture registers 1 + __IO uint32_t FCANIC1; +} LPC_CANAF_TypeDef; + +typedef struct /* Central Registers */ +{ + __I uint32_t TxSR; + __I uint32_t RxSR; + __I uint32_t MSR; +} LPC_CANCR_TypeDef; + +typedef struct /* Controller Registers */ +{ + ///Offset: 0x00000000 - Controls the operating mode of the CAN Controller + __IO uint32_t MOD; + + ///Offset: 0x00000004 - Command bits that affect the state + __O uint32_t CMR; + + ///Offset: 0x00000008 - Global Controller Status and Error Counters + __IO uint32_t GSR; + + ///Offset: 0x0000000C - Interrupt status, Arbitration Lost Capture, Error Code Capture + __I uint32_t ICR; + + ///Offset: 0x00000010 - Interrupt Enable Register + __IO uint32_t IER; + + ///Offset: 0x00000014 - Bus Timing Register + __IO uint32_t BTR; + + ///Offset: 0x00000018 - Error Warning Limit + __IO uint32_t EWL; + + ///Offset: 0x0000001C - Status Register + __I uint32_t SR; + + ///Offset: 0x00000020 - Receive frame status + __IO uint32_t RFS; + + ///Offset: 0x00000024 - Received Identifier + __IO uint32_t RID; + + ///Offset: 0x00000028 - Received data bytes 1-4 + __IO uint32_t RDA; + + ///Offset: 0x0000002C - Received data bytes 5-8 + __IO uint32_t RDB; + + ///Offset: 0x00000030 - Transmit frame info (Tx Buffer 1) + __IO uint32_t TFI1; + + ///Offset: 0x00000034 - Transmit Identifier (Tx Buffer 1) + __IO uint32_t TID1; + + ///Offset: 0x00000038 - Transmit data bytes 1-4 (Tx Buffer 1) + __IO uint32_t TDA1; + + ///Offset: 0x0000003C - Transmit data bytes 5-8 (Tx Buffer 1) + __IO uint32_t TDB1; + + ///Offset: 0x00000040 - Transmit frame info (Tx Buffer 2) + __IO uint32_t TFI2; + + ///Offset: 0x00000044 - Transmit Identifier (Tx Buffer 2) + __IO uint32_t TID2; + + ///Offset: 0x00000048 - Transmit data bytes 1-4 (Tx Buffer 2) + __IO uint32_t TDA2; + + ///Offset: 0x0000004C - Transmit data bytes 5-8 (Tx Buffer 2) + __IO uint32_t TDB2; + + ///Offset: 0x00000050 - Transmit frame info (Tx Buffer 3) + __IO uint32_t TFI3; + + ///Offset: 0x00000054 - Transmit Identifier (Tx Buffer 3) + __IO uint32_t TID3; + + ///Offset: 0x00000058 - Transmit data bytes 1-4 (Tx Buffer 3) + __IO uint32_t TDA3; + + ///Offset: 0x0000005C - Transmit data bytes 5-8 (Tx Buffer 3) + __IO uint32_t TDB3; +} LPC_CAN_TypeDef; + +/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/ +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CTRL; + __IO uint32_t CNTVAL; +} LPC_DAC_TypeDef; + + +/*------------- Inter IC Sound (I2S) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t DAO; + __IO uint32_t DAI; + __O uint32_t TXFIFO; + __I uint32_t RXFIFO; + __I uint32_t STATE; + __IO uint32_t DMA1; + __IO uint32_t DMA2; + __IO uint32_t IRQ; + __IO uint32_t TXRATE; + __IO uint32_t RXRATE; + __IO uint32_t TXBITRATE; + __IO uint32_t RXBITRATE; + __IO uint32_t TXMODE; + __IO uint32_t RXMODE; +} LPC_I2S_TypeDef; + + + + + + +/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/ +typedef struct +{ + __I uint32_t CON; + __O uint32_t CON_SET; + __O uint32_t CON_CLR; + __I uint32_t CAPCON; + __O uint32_t CAPCON_SET; + __O uint32_t CAPCON_CLR; + __IO uint32_t TC0; + __IO uint32_t TC1; + __IO uint32_t TC2; + __IO uint32_t LIM0; + __IO uint32_t LIM1; + __IO uint32_t LIM2; + __IO uint32_t MAT0; + __IO uint32_t MAT1; + __IO uint32_t MAT2; + __IO uint32_t DT; + __IO uint32_t CP; + __IO uint32_t CAP0; + __IO uint32_t CAP1; + __IO uint32_t CAP2; + __I uint32_t INTEN; + __O uint32_t INTEN_SET; + __O uint32_t INTEN_CLR; + __I uint32_t CNTCON; + __O uint32_t CNTCON_SET; + __O uint32_t CNTCON_CLR; + __I uint32_t INTF; + __O uint32_t INTF_SET; + __O uint32_t INTF_CLR; + __O uint32_t CAP_CLR; +} LPC_MCPWM_TypeDef; + +/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/ +typedef struct +{ + __O uint32_t CON; + __I uint32_t STAT; + __IO uint32_t CONF; + __I uint32_t POS; + __IO uint32_t MAXPOS; + __IO uint32_t CMPOS0; + __IO uint32_t CMPOS1; + __IO uint32_t CMPOS2; + __I uint32_t INXCNT; + __IO uint32_t INXCMP0; + __IO uint32_t LOAD; + __I uint32_t TIME; + __I uint32_t VEL; + __I uint32_t CAP; + __IO uint32_t VELCOMP; + __IO uint32_t FILTERPHA; + __IO uint32_t FILTERPHB; + __IO uint32_t FILTERINX; + __IO uint32_t WINDOW; + __IO uint32_t INXCMP1; + __IO uint32_t INXCMP2; + uint32_t RESERVED0[993]; + __O uint32_t IEC; + __O uint32_t IES; + __I uint32_t INTSTAT; + __I uint32_t IE; + __O uint32_t CLR; + __O uint32_t SET; +} LPC_QEI_TypeDef; + +/*------------- SD/MMC card Interface (MCI)-----------------------------------*/ +typedef struct +{ + __IO uint32_t POWER; + __IO uint32_t CLOCK; + __IO uint32_t ARGUMENT; + __IO uint32_t COMMAND; + __I uint32_t RESP_CMD; + __I uint32_t RESP0; + __I uint32_t RESP1; + __I uint32_t RESP2; + __I uint32_t RESP3; + __IO uint32_t DATATMR; + __IO uint32_t DATALEN; + __IO uint32_t DATACTRL; + __I uint32_t DATACNT; + __I uint32_t STATUS; + __O uint32_t CLEAR; + __IO uint32_t MASK0; + uint32_t RESERVED0[2]; + __I uint32_t FIFOCNT; + uint32_t RESERVED1[13]; + __IO uint32_t FIFO[16]; +} LPC_MCI_TypeDef; + + + + + + + + + + +/*------------- EEPROM Controller (EEPROM) -----------------------------------*/ +typedef struct +{ + __IO uint32_t CMD; /* 0x0080 */ + __IO uint32_t ADDR; + __IO uint32_t WDATA; + __IO uint32_t RDATA; + __IO uint32_t WSTATE; /* 0x0090 */ + __IO uint32_t CLKDIV; + __IO uint32_t PWRDWN; /* 0x0098 */ + uint32_t RESERVED0[975]; + __IO uint32_t INT_CLR_ENABLE; /* 0x0FD8 */ + __IO uint32_t INT_SET_ENABLE; + __IO uint32_t INT_STATUS; /* 0x0FE0 */ + __IO uint32_t INT_ENABLE; + __IO uint32_t INT_CLR_STATUS; + __IO uint32_t INT_SET_STATUS; +} LPC_EEPROM_TypeDef; + + +/*------------- COMPARATOR ----------------------------------------------------*/ + +typedef struct { /*!< (@ 0x40020000) COMPARATOR Structure */ + __IO uint32_t CTRL; /*!< (@ 0x40020000) Comparator block control register */ + __IO uint32_t CTRL0; /*!< (@ 0x40020004) Comparator 0 control register */ + __IO uint32_t CTRL1; /*!< (@ 0x40020008) Comparator 1 control register */ +} LPC_COMPARATOR_Type; + + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#elif defined ( __ICCARM__ ) +#pragma language=restore +#endif + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/* Base addresses */ +#define LPC_FLASH_BASE (0x00000000UL) +#define LPC_RAM_BASE (0x10000000UL) +#define LPC_PERI_RAM_BASE (0x20000000UL) +#define LPC_APB0_BASE (0x40000000UL) +#define LPC_APB1_BASE (0x40080000UL) +#define LPC_AHBRAM1_BASE (0x20004000UL) +#define LPC_AHB_BASE (0x20080000UL) +#define LPC_CM3_BASE (0xE0000000UL) + +/* APB0 peripherals */ +#define LPC_WDT_BASE (LPC_APB0_BASE + 0x00000) +#define LPC_TIM0_BASE (LPC_APB0_BASE + 0x04000) +#define LPC_TIM1_BASE (LPC_APB0_BASE + 0x08000) +#define LPC_UART0_BASE (LPC_APB0_BASE + 0x0C000) +#define LPC_UART1_BASE (LPC_APB0_BASE + 0x10000) +#define LPC_PWM0_BASE (LPC_APB0_BASE + 0x14000) +#define LPC_PWM1_BASE (LPC_APB0_BASE + 0x18000) +#define LPC_I2C0_BASE (LPC_APB0_BASE + 0x1C000) +#define LPC_COMPARATOR_BASE (LPC_APB0_BASE + 0x20000) +#define LPC_RTC_BASE (LPC_APB0_BASE + 0x24000) +#define LPC_GPIOINT_BASE (LPC_APB0_BASE + 0x28080) +#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x2C000) +#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x30000) +#define LPC_ADC_BASE (LPC_APB0_BASE + 0x34000) +#define LPC_CANAF_RAM_BASE (LPC_APB0_BASE + 0x38000) +#define LPC_CANAF_BASE (LPC_APB0_BASE + 0x3C000) +#define LPC_CANCR_BASE (LPC_APB0_BASE + 0x40000) +#define LPC_CAN1_BASE (LPC_APB0_BASE + 0x44000) +#define LPC_CAN2_BASE (LPC_APB0_BASE + 0x48000) +#define LPC_I2C1_BASE (LPC_APB0_BASE + 0x5C000) + +/* APB1 peripherals */ +#define LPC_SSP0_BASE (LPC_APB1_BASE + 0x08000) +#define LPC_DAC_BASE (LPC_APB1_BASE + 0x0C000) +#define LPC_TIM2_BASE (LPC_APB1_BASE + 0x10000) +#define LPC_TIM3_BASE (LPC_APB1_BASE + 0x14000) +#define LPC_UART2_BASE (LPC_APB1_BASE + 0x18000) +#define LPC_UART3_BASE (LPC_APB1_BASE + 0x1C000) +#define LPC_I2C2_BASE (LPC_APB1_BASE + 0x20000) +#define LPC_UART4_BASE (LPC_APB1_BASE + 0x24000) +#define LPC_I2S_BASE (LPC_APB1_BASE + 0x28000) +#define LPC_SSP2_BASE (LPC_APB1_BASE + 0x2C000) +#define LPC_MCPWM_BASE (LPC_APB1_BASE + 0x38000) +#define LPC_QEI_BASE (LPC_APB1_BASE + 0x3C000) +#define LPC_MCI_BASE (LPC_APB1_BASE + 0x40000) +#define LPC_SC_BASE (LPC_APB1_BASE + 0x7C000) + +/* AHB peripherals */ +#define LPC_GPDMA_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPDMACH0_BASE (LPC_AHB_BASE + 0x00100) +#define LPC_GPDMACH1_BASE (LPC_AHB_BASE + 0x00120) +#define LPC_GPDMACH2_BASE (LPC_AHB_BASE + 0x00140) +#define LPC_GPDMACH3_BASE (LPC_AHB_BASE + 0x00160) +#define LPC_GPDMACH4_BASE (LPC_AHB_BASE + 0x00180) +#define LPC_GPDMACH5_BASE (LPC_AHB_BASE + 0x001A0) +#define LPC_GPDMACH6_BASE (LPC_AHB_BASE + 0x001C0) +#define LPC_GPDMACH7_BASE (LPC_AHB_BASE + 0x001E0) +#define LPC_EMAC_BASE (LPC_AHB_BASE + 0x04000) +#define LPC_LCD_BASE (LPC_AHB_BASE + 0x08000) +#define LPC_USB_BASE (LPC_AHB_BASE + 0x0C000) +#define LPC_CRC_BASE (LPC_AHB_BASE + 0x10000) +#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x18000) +#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x18020) +#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x18040) +#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x18060) +#define LPC_GPIO4_BASE (LPC_AHB_BASE + 0x18080) +#define LPC_GPIO5_BASE (LPC_AHB_BASE + 0x180A0) +#define LPC_EMC_BASE (LPC_AHB_BASE + 0x1C000) + +#define LPC_EEPROM_BASE (LPC_FLASH_BASE+ 0x200080) + + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define LPC_SC ((LPC_SC_TypeDef *) LPC_SC_BASE ) +#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE ) +#define LPC_TIM0 ((LPC_TIM_TypeDef *) LPC_TIM0_BASE ) +#define LPC_TIM1 ((LPC_TIM_TypeDef *) LPC_TIM1_BASE ) +#define LPC_TIM2 ((LPC_TIM_TypeDef *) LPC_TIM2_BASE ) +#define LPC_TIM3 ((LPC_TIM_TypeDef *) LPC_TIM3_BASE ) +#define LPC_UART0 ((LPC_UART_TypeDef *) LPC_UART0_BASE ) +#define LPC_UART1 ((LPC_UART1_TypeDef *) LPC_UART1_BASE ) +#define LPC_UART2 ((LPC_UART_TypeDef *) LPC_UART2_BASE ) +#define LPC_UART3 ((LPC_UART_TypeDef *) LPC_UART3_BASE ) +#define LPC_UART4 ((LPC_UART4_TypeDef *) LPC_UART4_BASE ) +#define LPC_PWM0 ((LPC_PWM_TypeDef *) LPC_PWM0_BASE ) +#define LPC_PWM1 ((LPC_PWM_TypeDef *) LPC_PWM1_BASE ) +#define LPC_I2C0 ((LPC_I2C_TypeDef *) LPC_I2C0_BASE ) +#define LPC_I2C1 ((LPC_I2C_TypeDef *) LPC_I2C1_BASE ) +#define LPC_I2C2 ((LPC_I2C_TypeDef *) LPC_I2C2_BASE ) +#define LPC_I2S ((LPC_I2S_TypeDef *) LPC_I2S_BASE ) +#define LPC_COMPARATOR ((LPC_COMPARATOR_Type *) LPC_COMPARATOR_BASE) +#define LPC_RTC ((LPC_RTC_TypeDef *) LPC_RTC_BASE ) +#define LPC_GPIOINT ((LPC_GPIOINT_TypeDef *) LPC_GPIOINT_BASE ) +#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE ) +#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE ) +#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE ) +#define LPC_SSP2 ((LPC_SSP_TypeDef *) LPC_SSP2_BASE ) +#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE ) +#define LPC_DAC ((LPC_DAC_TypeDef *) LPC_DAC_BASE ) +#define LPC_CANAF_RAM ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE) +#define LPC_CANAF ((LPC_CANAF_TypeDef *) LPC_CANAF_BASE ) +#define LPC_CANCR ((LPC_CANCR_TypeDef *) LPC_CANCR_BASE ) +#define LPC_CAN1 ((LPC_CAN_TypeDef *) LPC_CAN1_BASE ) +#define LPC_CAN2 ((LPC_CAN_TypeDef *) LPC_CAN2_BASE ) +#define LPC_MCPWM ((LPC_MCPWM_TypeDef *) LPC_MCPWM_BASE ) +#define LPC_QEI ((LPC_QEI_TypeDef *) LPC_QEI_BASE ) +#define LPC_MCI ((LPC_MCI_TypeDef *) LPC_MCI_BASE ) +#define LPC_GPDMA ((LPC_GPDMA_TypeDef *) LPC_GPDMA_BASE ) +#define LPC_GPDMACH0 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH0_BASE ) +#define LPC_GPDMACH1 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH1_BASE ) +#define LPC_GPDMACH2 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH2_BASE ) +#define LPC_GPDMACH3 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH3_BASE ) +#define LPC_GPDMACH4 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH4_BASE ) +#define LPC_GPDMACH5 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH5_BASE ) +#define LPC_GPDMACH6 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH6_BASE ) +#define LPC_GPDMACH7 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH7_BASE ) +#define LPC_EMAC ((LPC_EMAC_TypeDef *) LPC_EMAC_BASE ) +#define LPC_LCD ((LPC_LCD_TypeDef *) LPC_LCD_BASE ) +#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE ) +#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE ) +#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE ) +#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE ) +#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE ) +#define LPC_GPIO4 ((LPC_GPIO_TypeDef *) LPC_GPIO4_BASE ) +#define LPC_GPIO5 ((LPC_GPIO_TypeDef *) LPC_GPIO5_BASE ) +#define LPC_EMC ((LPC_EMC_TypeDef *) LPC_EMC_BASE ) +#define LPC_CRC ((LPC_CRC_TypeDef *) LPC_CRC_BASE ) +#define LPC_EEPROM ((LPC_EEPROM_TypeDef *) LPC_EEPROM_BASE ) + + + +#endif // __LPC407x_8x_177x_8x_H__ diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC177x_8x.h b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC177x_8x.h new file mode 100644 index 0000000000000000000000000000000000000000..464225eca38ee6c416dd58070afdfd82d7176ee9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC177x_8x.h @@ -0,0 +1,89 @@ +/********************************************************************** +* $Id$ system_LPC177x_8x.h 2011-06-02 +*//** +* @file system_LPC177x_8x.h +* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File +* for the NXP LPC177x_8x Device Series +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 __SYSTEM_LPC177x_8x_H +#define __SYSTEM_LPC177x_8x_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency (Pclk) */ +extern uint32_t EMCClock; /*!< EMC Clock */ +extern uint32_t USBClock; /*!< USB Frequency */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define XTAL (12000000UL) /* Oscillator frequency */ +#define OSC_CLK ( XTAL) /* Main oscillator frequency */ +#define RTC_CLK ( 32768UL) /* RTC oscillator frequency */ +#define IRC_OSC (12000000UL) /* Internal RC oscillator frequency */ +#define WDT_OSC ( 500000UL) /* Internal WDT oscillator frequency */ + + + +/* +//-------- <<< end of configuration section >>> ------------------------------ +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_LPC177x_8x_H */ diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC407x_8x_177x_8x.h b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC407x_8x_177x_8x.h new file mode 100644 index 0000000000000000000000000000000000000000..18a54a0d7f5aa64f77211914f97a4f7fb539013f --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Include/system_LPC407x_8x_177x_8x.h @@ -0,0 +1,89 @@ +/********************************************************************** +* $Id$ system_LPC407x_8x_177x_8x.h 2011-06-02 +*//** +* @file system_LPC407x_8x_177x_8x.h +* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File +* for the NXP LPC Device Series +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 __SYSTEM_LPC407x_8x_177x_8x_H +#define __SYSTEM_LPC407x_8x_177x_8x_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency (Pclk) */ +extern uint32_t EMCClock; /*!< EMC Clock */ +extern uint32_t USBClock; /*!< USB Frequency */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define XTAL (12000000UL) /* Oscillator frequency */ +#define OSC_CLK ( XTAL) /* Main oscillator frequency */ +#define RTC_CLK ( 32768UL) /* RTC oscillator frequency */ +#define IRC_OSC (12000000UL) /* Internal RC oscillator frequency */ +#define WDT_OSC ( 500000UL) /* Internal WDT oscillator frequency */ + + + +/* +//-------- <<< end of configuration section >>> ------------------------------ +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_LPC407x_8x_177x_8x_H */ diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..59cc885de3d6faa4b6b11139737904b570557ae9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC177x_8x.s @@ -0,0 +1,301 @@ +;/***************************************************************************** +; * @file: startup_LPC177x_8x.s +; * @purpose: CMSIS Cortex-M3 Core Device Startup File +; * for the NXP LPC177x_8x Device Series +; * @version: V1.20 +; * @date: 07. October 2010 +; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +; * +; * Copyright (C) 2010 ARM Limited. All rights reserved. +; * ARM Limited (ARM) is supplying this software for use with Cortex-M3 +; * 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. +; * +; *****************************************************************************/ + + +; 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 MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WDT_IRQHandler ; 16: Watchdog Timer + DCD TIMER0_IRQHandler ; 17: Timer0 + DCD TIMER1_IRQHandler ; 18: Timer1 + DCD TIMER2_IRQHandler ; 19: Timer2 + DCD TIMER3_IRQHandler ; 20: Timer3 + DCD UART0_IRQHandler ; 21: UART0 + DCD UART1_IRQHandler ; 22: UART1 + DCD UART2_IRQHandler ; 23: UART2 + DCD UART3_IRQHandler ; 24: UART3 + DCD PWM1_IRQHandler ; 25: PWM1 + DCD I2C0_IRQHandler ; 26: I2C0 + DCD I2C1_IRQHandler ; 27: I2C1 + DCD I2C2_IRQHandler ; 28: I2C2 + DCD 0 ; 29: reserved, not for SPIFI anymore + DCD SSP0_IRQHandler ; 30: SSP0 + DCD SSP1_IRQHandler ; 31: SSP1 + DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL) + DCD RTC_IRQHandler ; 33: Real Time Clock + DCD EINT0_IRQHandler ; 34: External Interrupt 0 + DCD EINT1_IRQHandler ; 35: External Interrupt 1 + DCD EINT2_IRQHandler ; 36: External Interrupt 2 + DCD EINT3_IRQHandler ; 37: External Interrupt 3 + DCD ADC_IRQHandler ; 38: A/D Converter + DCD BOD_IRQHandler ; 39: Brown-Out Detect + DCD USB_IRQHandler ; 40: USB + DCD CAN_IRQHandler ; 41: CAN + DCD DMA_IRQHandler ; 42: General Purpose DMA + DCD I2S_IRQHandler ; 43: I2S + DCD ENET_IRQHandler ; 44: Ethernet + DCD MCI_IRQHandler ; 45: SD/MMC card I/F + DCD MCPWM_IRQHandler ; 46: Motor Control PWM + DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface + DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL) + DCD USBActivity_IRQHandler ; 49: USB Activity interrupt to wakeup + DCD CANActivity_IRQHandler ; 50: CAN Activity interrupt to wakeup + DCD UART4_IRQHandler ; 51: UART4 + DCD SSP2_IRQHandler ; 52: SSP2 + DCD LCD_IRQHandler ; 53: LCD + DCD GPIO_IRQHandler ; 54: GPIO + DCD PWM0_IRQHandler ; 55: PWM0 + DCD EEPROM_IRQHandler ; 56: EEPROM + + + IF :LNOT::DEF:NO_CRP + AREA |.ARM.__at_0x02FC|, CODE, READONLY +CRP_Key DCD 0xFFFFFFFF + ENDIF + + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +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] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT UART0_IRQHandler [WEAK] + EXPORT UART1_IRQHandler [WEAK] + EXPORT UART2_IRQHandler [WEAK] + EXPORT UART3_IRQHandler [WEAK] + EXPORT PWM1_IRQHandler [WEAK] + EXPORT I2C0_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + ;EXPORT SPIFI_IRQHandler [WEAK] + EXPORT SSP0_IRQHandler [WEAK] + EXPORT SSP1_IRQHandler [WEAK] + EXPORT PLL0_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT EINT0_IRQHandler [WEAK] + EXPORT EINT1_IRQHandler [WEAK] + EXPORT EINT2_IRQHandler [WEAK] + EXPORT EINT3_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT BOD_IRQHandler [WEAK] + EXPORT USB_IRQHandler [WEAK] + EXPORT CAN_IRQHandler [WEAK] + EXPORT DMA_IRQHandler [WEAK] + EXPORT I2S_IRQHandler [WEAK] + EXPORT ENET_IRQHandler [WEAK] + EXPORT MCI_IRQHandler [WEAK] + EXPORT MCPWM_IRQHandler [WEAK] + EXPORT QEI_IRQHandler [WEAK] + EXPORT PLL1_IRQHandler [WEAK] + EXPORT USBActivity_IRQHandler [WEAK] + EXPORT CANActivity_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT SSP2_IRQHandler [WEAK] + EXPORT LCD_IRQHandler [WEAK] + EXPORT GPIO_IRQHandler [WEAK] + EXPORT PWM0_IRQHandler [WEAK] + EXPORT EEPROM_IRQHandler [WEAK] + +WDT_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER3_IRQHandler +UART0_IRQHandler +UART1_IRQHandler +UART2_IRQHandler +UART3_IRQHandler +PWM1_IRQHandler +I2C0_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +;SPIFI_IRQHandler ;not used +SSP0_IRQHandler +SSP1_IRQHandler +PLL0_IRQHandler +RTC_IRQHandler +EINT0_IRQHandler +EINT1_IRQHandler +EINT2_IRQHandler +EINT3_IRQHandler +ADC_IRQHandler +BOD_IRQHandler +USB_IRQHandler +CAN_IRQHandler +DMA_IRQHandler +I2S_IRQHandler +ENET_IRQHandler +MCI_IRQHandler +MCPWM_IRQHandler +QEI_IRQHandler +PLL1_IRQHandler +USBActivity_IRQHandler +CANActivity_IRQHandler +UART4_IRQHandler +SSP2_IRQHandler +LCD_IRQHandler +GPIO_IRQHandler +PWM0_IRQHandler +EEPROM_IRQHandler + + B . + + ENDP + + + ALIGN + + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + + END diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC407x_8x_177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC407x_8x_177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..bca9de93c87f0c7a152c11bf732ff1a44c67e3c3 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC407x_8x_177x_8x.s @@ -0,0 +1,302 @@ +;/***************************************************************************** +; * @file: startup_LPC407x_8x.s +; * @purpose: CMSIS Cortex-M4 Core Device Startup File +; * for the NXP LPC407x_8x Device Series +; * @version: V1.20 +; * @date: 16. January 2012 +; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +; * +; * Copyright (C) 2012 ARM Limited. All rights reserved. +; * ARM Limited (ARM) is supplying this software for use with Cortex-M4 +; * 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. +; * +; *****************************************************************************/ + + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + 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 MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + ; DCD 0xEFFFF5D6 ; Reserved- vector sum + DCD 0xEFFFF39E ; Reserved- vector sum + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WDT_IRQHandler ; 16: Watchdog Timer + DCD TIMER0_IRQHandler ; 17: Timer0 + DCD TIMER1_IRQHandler ; 18: Timer1 + DCD TIMER2_IRQHandler ; 19: Timer2 + DCD TIMER3_IRQHandler ; 20: Timer3 + DCD UART0_IRQHandler ; 21: UART0 + DCD UART1_IRQHandler ; 22: UART1 + DCD UART2_IRQHandler ; 23: UART2 + DCD UART3_IRQHandler ; 24: UART3 + DCD PWM1_IRQHandler ; 25: PWM1 + DCD I2C0_IRQHandler ; 26: I2C0 + DCD I2C1_IRQHandler ; 27: I2C1 + DCD I2C2_IRQHandler ; 28: I2C2 + DCD 0 ; 29: reserved, not for SPIFI anymore + DCD SSP0_IRQHandler ; 30: SSP0 + DCD SSP1_IRQHandler ; 31: SSP1 + DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL) + DCD RTC_IRQHandler ; 33: Real Time Clock + DCD EINT0_IRQHandler ; 34: External Interrupt 0 + DCD EINT1_IRQHandler ; 35: External Interrupt 1 + DCD EINT2_IRQHandler ; 36: External Interrupt 2 + DCD EINT3_IRQHandler ; 37: External Interrupt 3 + DCD ADC_IRQHandler ; 38: A/D Converter + DCD BOD_IRQHandler ; 39: Brown-Out Detect + DCD USB_IRQHandler ; 40: USB + DCD CAN_IRQHandler ; 41: CAN + DCD DMA_IRQHandler ; 42: General Purpose DMA + DCD I2S_IRQHandler ; 43: I2S + DCD ENET_IRQHandler ; 44: Ethernet + DCD MCI_IRQHandler ; 45: SD/MMC card I/F + DCD MCPWM_IRQHandler ; 46: Motor Control PWM + DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface + DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL) + DCD USBActivity_IRQHandler ; 49: USB Activity interrupt to wakeup + DCD CANActivity_IRQHandler ; 50: CAN Activity interrupt to wakeup + DCD UART4_IRQHandler ; 51: UART4 + DCD SSP2_IRQHandler ; 52: SSP2 + DCD LCD_IRQHandler ; 53: LCD + DCD GPIO_IRQHandler ; 54: GPIO + DCD PWM0_IRQHandler ; 55: PWM0 + DCD EEPROM_IRQHandler ; 56: EEPROM + + + IF :LNOT::DEF:NO_CRP + AREA |.ARM.__at_0x02FC|, CODE, READONLY +CRP_Key DCD 0xFFFFFFFF + ENDIF + + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +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] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT UART0_IRQHandler [WEAK] + EXPORT UART1_IRQHandler [WEAK] + EXPORT UART2_IRQHandler [WEAK] + EXPORT UART3_IRQHandler [WEAK] + EXPORT PWM1_IRQHandler [WEAK] + EXPORT I2C0_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + ;EXPORT SPIFI_IRQHandler [WEAK] + EXPORT SSP0_IRQHandler [WEAK] + EXPORT SSP1_IRQHandler [WEAK] + EXPORT PLL0_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT EINT0_IRQHandler [WEAK] + EXPORT EINT1_IRQHandler [WEAK] + EXPORT EINT2_IRQHandler [WEAK] + EXPORT EINT3_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT BOD_IRQHandler [WEAK] + EXPORT USB_IRQHandler [WEAK] + EXPORT CAN_IRQHandler [WEAK] + EXPORT DMA_IRQHandler [WEAK] + EXPORT I2S_IRQHandler [WEAK] + EXPORT ENET_IRQHandler [WEAK] + EXPORT MCI_IRQHandler [WEAK] + EXPORT MCPWM_IRQHandler [WEAK] + EXPORT QEI_IRQHandler [WEAK] + EXPORT PLL1_IRQHandler [WEAK] + EXPORT USBActivity_IRQHandler [WEAK] + EXPORT CANActivity_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT SSP2_IRQHandler [WEAK] + EXPORT LCD_IRQHandler [WEAK] + EXPORT GPIO_IRQHandler [WEAK] + EXPORT PWM0_IRQHandler [WEAK] + EXPORT EEPROM_IRQHandler [WEAK] + +WDT_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER3_IRQHandler +UART0_IRQHandler +UART1_IRQHandler +UART2_IRQHandler +UART3_IRQHandler +PWM1_IRQHandler +I2C0_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +;SPIFI_IRQHandler ;not used +SSP0_IRQHandler +SSP1_IRQHandler +PLL0_IRQHandler +RTC_IRQHandler +EINT0_IRQHandler +EINT1_IRQHandler +EINT2_IRQHandler +EINT3_IRQHandler +ADC_IRQHandler +BOD_IRQHandler +USB_IRQHandler +CAN_IRQHandler +DMA_IRQHandler +I2S_IRQHandler +ENET_IRQHandler +MCI_IRQHandler +MCPWM_IRQHandler +QEI_IRQHandler +PLL1_IRQHandler +USBActivity_IRQHandler +CANActivity_IRQHandler +UART4_IRQHandler +SSP2_IRQHandler +LCD_IRQHandler +GPIO_IRQHandler +PWM0_IRQHandler +EEPROM_IRQHandler + + B . + + ENDP + + + ALIGN + + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + + END diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..5d966a39b33602da3f8a728a31b3f5daac6b50dc --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC177x_8x.s @@ -0,0 +1,279 @@ +/*****************************************************************************/ +/* startup_LPC17xx.s: Startup file for LPC17xx device series */ +/*****************************************************************************/ +/* Version: CodeSourcery Sourcery G++ Lite (with CS3) */ +/*****************************************************************************/ + + +/* +//*** <<< Use Configuration Wizard in Context Menu >>> *** +*/ + + +/* +// Stack Configuration +// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +*/ + + .equ Stack_Size, 0x00000100 + .section ".stack", "w" + .align 3 + .globl __cs3_stack_mem + .globl __cs3_stack_size +__cs3_stack_mem: + .if Stack_Size + .space Stack_Size + .endif + .size __cs3_stack_mem, . - __cs3_stack_mem + .set __cs3_stack_size, . - __cs3_stack_mem + + +/* +// Heap Configuration +// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +*/ + + .equ Heap_Size, 0x00001000 + + .section ".heap", "w" + .align 3 + .globl __cs3_heap_start + .globl __cs3_heap_end +__cs3_heap_start: + .if Heap_Size + .space Heap_Size + .endif +__cs3_heap_end: + + +/* Vector Table */ + + .section ".cs3.interrupt_vector" + .globl __cs3_interrupt_vector_cortex_m + .type __cs3_interrupt_vector_cortex_m, %object + +__cs3_interrupt_vector_cortex_m: + .long __cs3_stack /* Top of Stack */ + .long __cs3_reset /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External Interrupts */ + .long WDT_IRQHandler /* 16: Watchdog Timer */ + .long TIMER0_IRQHandler /* 17: Timer0 */ + .long TIMER1_IRQHandler /* 18: Timer1 */ + .long TIMER2_IRQHandler /* 19: Timer2 */ + .long TIMER3_IRQHandler /* 20: Timer3 */ + .long UART0_IRQHandler /* 21: UART0 */ + .long UART1_IRQHandler /* 22: UART1 */ + .long UART2_IRQHandler /* 23: UART2 */ + .long UART3_IRQHandler /* 24: UART3 */ + .long PWM1_IRQHandler /* 25: PWM1 */ + .long I2C0_IRQHandler /* 26: I2C0 */ + .long I2C1_IRQHandler /* 27: I2C1 */ + .long I2C2_IRQHandler /* 28: I2C2 */ + .long 0 /* 29: Reserved, not for SPIFI anymore */ + .long SSP0_IRQHandler /* 30: SSP0 */ + .long SSP1_IRQHandler /* 31: SSP1 */ + .long PLL0_IRQHandler /* 32: PLL0 Lock (Main PLL) */ + .long RTC_IRQHandler /* 33: Real Time Clock */ + .long EINT0_IRQHandler /* 34: External Interrupt 0 */ + .long EINT1_IRQHandler /* 35: External Interrupt 1 */ + .long EINT2_IRQHandler /* 36: External Interrupt 2 */ + .long EINT3_IRQHandler /* 37: External Interrupt 3 */ + .long ADC_IRQHandler /* 38: A/D Converter */ + .long BOD_IRQHandler /* 39: Brown-Out Detect */ + .long USB_IRQHandler /* 40: USB */ + .long CAN_IRQHandler /* 41: CAN */ + .long DMA_IRQHandler /* 42: General Purpose DMA */ + .long I2S_IRQHandler /* 43: I2S */ + .long ENET_IRQHandler /* 44: Ethernet */ + .long MCI_IRQHandler /* 45: SD/MMC Card */ + .long MCPWM_IRQHandler /* 46: Motor Control PWM */ + .long QEI_IRQHandler /* 47: Quadrature Encoder Interface */ + .long PLL1_IRQHandler /* 48: PLL1 Lock (USB PLL) */ + .long USBActivity_IRQHandler /* 49: USB Activity */ + .long CANActivity_IRQHandler /* 50: CAN Activity */ + .long UART4_IRQHandler /* 51: UART4 */ + .long SSP2_IRQHandler /* 52: SSP2 */ + .long LCD_IRQHandler /* 53: LCD */ + .long GPIO_IRQHandler /* 54: GPIO */ + .long PWM0_IRQHandler /* 55: PWM0 */ + .long EEPROM_IRQHandler /* 56: EEPROM */ + + .size __cs3_interrupt_vector_cortex_m, . - __cs3_interrupt_vector_cortex_m + + + .thumb + + .section ".crp" + .globl CRP_Value +CRP_Value: + .long 0xFFFFFFFF + +/* Reset Handler */ + + .section .cs3.reset,"x",%progbits + .thumb_func + .globl __cs3_reset_cortex_m + .type __cs3_reset_cortex_m, %function +__cs3_reset_cortex_m: + .fnstart +.if (RAM_MODE) +/* Clear .bss section (Zero init) */ + MOV R0, #0 + LDR R1, =__bss_start__ + LDR R2, =__bss_end__ + CMP R1,R2 + BEQ BSSIsEmpty +LoopZI: + CMP R1, R2 + BHS BSSIsEmpty + STR R0, [R1] + ADD R1, #4 + BLO LoopZI +BSSIsEmpty: + LDR R0, =SystemInit + BLX R0 + LDR R0,=main + BX R0 +.else + LDR R0, =SystemInit + BLX R0 + LDR R0,=_start + BX R0 +.endif + .pool + .cantunwind + .fnend + .size __cs3_reset_cortex_m,.-__cs3_reset_cortex_m + + .section ".text" + +/* Exception Handlers */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + B . + .size NMI_Handler, . - NMI_Handler + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + B . + .size HardFault_Handler, . - HardFault_Handler + + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + B . + .size MemManage_Handler, . - MemManage_Handler + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + B . + .size BusFault_Handler, . - BusFault_Handler + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + B . + .size UsageFault_Handler, . - UsageFault_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + B . + .size SVC_Handler, . - SVC_Handler + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + B . + .size DebugMon_Handler, . - DebugMon_Handler + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + B . + .size PendSV_Handler, . - PendSV_Handler + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + B . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + B . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ WDT_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ TIMER3_IRQHandler + IRQ UART0_IRQHandler + IRQ UART1_IRQHandler + IRQ UART2_IRQHandler + IRQ UART3_IRQHandler + IRQ PWM1_IRQHandler + IRQ I2C0_IRQHandler + IRQ I2C1_IRQHandler + IRQ I2C2_IRQHandler +/* IRQ SPIFI_IRQHandler */ + IRQ SSP0_IRQHandler + IRQ SSP1_IRQHandler + IRQ PLL0_IRQHandler + IRQ RTC_IRQHandler + IRQ EINT0_IRQHandler + IRQ EINT1_IRQHandler + IRQ EINT2_IRQHandler + IRQ EINT3_IRQHandler + IRQ ADC_IRQHandler + IRQ BOD_IRQHandler + IRQ USB_IRQHandler + IRQ CAN_IRQHandler + IRQ DMA_IRQHandler + IRQ I2S_IRQHandler + IRQ ENET_IRQHandler + IRQ MCI_IRQHandler + IRQ MCPWM_IRQHandler + IRQ QEI_IRQHandler + IRQ PLL1_IRQHandler + IRQ USBActivity_IRQHandler + IRQ CANActivity_IRQHandler + IRQ UART4_IRQHandler + IRQ SSP2_IRQHandler + IRQ LCD_IRQHandler + IRQ GPIO_IRQHandler + IRQ PWM0_IRQHandler + IRQ EEPROM_IRQHandler + + .end diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC407x_8x_177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC407x_8x_177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..f78e553073c499fe897ad7958495eb2b4b90a554 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC407x_8x_177x_8x.s @@ -0,0 +1,279 @@ +/*****************************************************************************/ +/* startup_LPC17xx.s: Startup file for LPC17xx device series */ +/*****************************************************************************/ +/* Version: CodeSourcery Sourcery G++ Lite (with CS3) */ +/*****************************************************************************/ + + +/* +//*** <<< Use Configuration Wizard in Context Menu >>> *** +*/ + + +/* +// Stack Configuration +// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +*/ + + .equ Stack_Size, 0x00000100 + .section ".stack", "w" + .align 3 + .globl __cs3_stack_mem + .globl __cs3_stack_size +__cs3_stack_mem: + .if Stack_Size + .space Stack_Size + .endif + .size __cs3_stack_mem, . - __cs3_stack_mem + .set __cs3_stack_size, . - __cs3_stack_mem + + +/* +// Heap Configuration +// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +*/ + + .equ Heap_Size, 0x00001000 + + .section ".heap", "w" + .align 3 + .globl __cs3_heap_start + .globl __cs3_heap_end +__cs3_heap_start: + .if Heap_Size + .space Heap_Size + .endif +__cs3_heap_end: + + +/* Vector Table */ + + .section ".cs3.interrupt_vector" + .globl __cs3_interrupt_vector_cortex_m + .type __cs3_interrupt_vector_cortex_m, %object + +__cs3_interrupt_vector_cortex_m: + .long __cs3_stack /* Top of Stack */ + .long __cs3_reset /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External Interrupts */ + .long WDT_IRQHandler /* 16: Watchdog Timer */ + .long TIMER0_IRQHandler /* 17: Timer0 */ + .long TIMER1_IRQHandler /* 18: Timer1 */ + .long TIMER2_IRQHandler /* 19: Timer2 */ + .long TIMER3_IRQHandler /* 20: Timer3 */ + .long UART0_IRQHandler /* 21: UART0 */ + .long UART1_IRQHandler /* 22: UART1 */ + .long UART2_IRQHandler /* 23: UART2 */ + .long UART3_IRQHandler /* 24: UART3 */ + .long PWM1_IRQHandler /* 25: PWM1 */ + .long I2C0_IRQHandler /* 26: I2C0 */ + .long I2C1_IRQHandler /* 27: I2C1 */ + .long I2C2_IRQHandler /* 28: I2C2 */ + .long 0 /* 29: Reserved, not for SPIFI anymore */ + .long SSP0_IRQHandler /* 30: SSP0 */ + .long SSP1_IRQHandler /* 31: SSP1 */ + .long PLL0_IRQHandler /* 32: PLL0 Lock (Main PLL) */ + .long RTC_IRQHandler /* 33: Real Time Clock */ + .long EINT0_IRQHandler /* 34: External Interrupt 0 */ + .long EINT1_IRQHandler /* 35: External Interrupt 1 */ + .long EINT2_IRQHandler /* 36: External Interrupt 2 */ + .long EINT3_IRQHandler /* 37: External Interrupt 3 */ + .long ADC_IRQHandler /* 38: A/D Converter */ + .long BOD_IRQHandler /* 39: Brown-Out Detect */ + .long USB_IRQHandler /* 40: USB */ + .long CAN_IRQHandler /* 41: CAN */ + .long DMA_IRQHandler /* 42: General Purpose DMA */ + .long I2S_IRQHandler /* 43: I2S */ + .long ENET_IRQHandler /* 44: Ethernet */ + .long MCI_IRQHandler /* 45: SD/MMC Card */ + .long MCPWM_IRQHandler /* 46: Motor Control PWM */ + .long QEI_IRQHandler /* 47: Quadrature Encoder Interface */ + .long PLL1_IRQHandler /* 48: PLL1 Lock (USB PLL) */ + .long USBActivity_IRQHandler /* 49: USB Activity */ + .long CANActivity_IRQHandler /* 50: CAN Activity */ + .long UART4_IRQHandler /* 51: UART4 */ + .long SSP2_IRQHandler /* 52: SSP2 */ + .long LCD_IRQHandler /* 53: LCD */ + .long GPIO_IRQHandler /* 54: GPIO */ + .long PWM0_IRQHandler /* 55: PWM0 */ + .long EEPROM_IRQHandler /* 56: EEPROM */ + + .size __cs3_interrupt_vector_cortex_m, . - __cs3_interrupt_vector_cortex_m + + + .thumb + + .section ".crp" + .globl CRP_Value +CRP_Value: + .long 0xFFFFFFFF + +/* Reset Handler */ + + .section .cs3.reset,"x",%progbits + .thumb_func + .globl __cs3_reset_cortex_m + .type __cs3_reset_cortex_m, %function +__cs3_reset_cortex_m: + .fnstart +.ifdef RAM_MODE +/* Clear .bss section (Zero init) */ + MOV R0, #0 + LDR R1, =__bss_start__ + LDR R2, =__bss_end__ + CMP R1,R2 + BEQ BSSIsEmpty +LoopZI: + CMP R1, R2 + BHS BSSIsEmpty + STR R0, [R1] + ADD R1, #4 + BLO LoopZI +BSSIsEmpty: + LDR R0, =SystemInit + BLX R0 + LDR R0,=main + BX R0 +.else + LDR R0, =SystemInit + BLX R0 + LDR R0,=_start + BX R0 +.endif + .pool + .cantunwind + .fnend + .size __cs3_reset_cortex_m,.-__cs3_reset_cortex_m + + .section ".text" + +/* Exception Handlers */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + B . + .size NMI_Handler, . - NMI_Handler + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + B . + .size HardFault_Handler, . - HardFault_Handler + + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + B . + .size MemManage_Handler, . - MemManage_Handler + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + B . + .size BusFault_Handler, . - BusFault_Handler + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + B . + .size UsageFault_Handler, . - UsageFault_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + B . + .size SVC_Handler, . - SVC_Handler + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + B . + .size DebugMon_Handler, . - DebugMon_Handler + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + B . + .size PendSV_Handler, . - PendSV_Handler + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + B . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + B . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ WDT_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ TIMER3_IRQHandler + IRQ UART0_IRQHandler + IRQ UART1_IRQHandler + IRQ UART2_IRQHandler + IRQ UART3_IRQHandler + IRQ PWM1_IRQHandler + IRQ I2C0_IRQHandler + IRQ I2C1_IRQHandler + IRQ I2C2_IRQHandler +/* IRQ SPIFI_IRQHandler */ + IRQ SSP0_IRQHandler + IRQ SSP1_IRQHandler + IRQ PLL0_IRQHandler + IRQ RTC_IRQHandler + IRQ EINT0_IRQHandler + IRQ EINT1_IRQHandler + IRQ EINT2_IRQHandler + IRQ EINT3_IRQHandler + IRQ ADC_IRQHandler + IRQ BOD_IRQHandler + IRQ USB_IRQHandler + IRQ CAN_IRQHandler + IRQ DMA_IRQHandler + IRQ I2S_IRQHandler + IRQ ENET_IRQHandler + IRQ MCI_IRQHandler + IRQ MCPWM_IRQHandler + IRQ QEI_IRQHandler + IRQ PLL1_IRQHandler + IRQ USBActivity_IRQHandler + IRQ CANActivity_IRQHandler + IRQ UART4_IRQHandler + IRQ SSP2_IRQHandler + IRQ LCD_IRQHandler + IRQ GPIO_IRQHandler + IRQ PWM0_IRQHandler + IRQ EEPROM_IRQHandler + + .end diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..55f4be7484f7df042cb09d66e47875d0a61f7833 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC177x_8x.s @@ -0,0 +1,396 @@ +;/***************************************************************************** +; * @file: startup_LPC177x_8x.s +; * @purpose: CMSIS Cortex-M3 Core Device Startup File +; * for the NXP LPC17xx Device Series +; * @version: V1.03 +; * @date: 09. February 2010 +; *---------------------------------------------------------------------------- +; * +; * Copyright (C) 2010 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 + EXTERN SystemInit + 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 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_IRQHandler ; 16: Watchdog Timer + DCD TIMER0_IRQHandler ; 17: Timer0 + DCD TIMER1_IRQHandler ; 18: Timer1 + DCD TIMER2_IRQHandler ; 19: Timer2 + DCD TIMER3_IRQHandler ; 20: Timer3 + DCD UART0_IRQHandler ; 21: UART0 + DCD UART1_IRQHandler ; 22: UART1 + DCD UART2_IRQHandler ; 23: UART2 + DCD UART3_IRQHandler ; 24: UART3 + DCD PWM1_IRQHandler ; 25: PWM1 + DCD I2C0_IRQHandler ; 26: I2C0 + DCD I2C1_IRQHandler ; 27: I2C1 + DCD I2C2_IRQHandler ; 28: I2C2 + DCD 0 ; 29: reserved; not for SPIFI anymore + DCD SSP0_IRQHandler ; 30: SSP0 + DCD SSP1_IRQHandler ; 31: SSP1 + DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL) + DCD RTC_IRQHandler ; 33: Real Time Clock + DCD EINT0_IRQHandler ; 34: External Interrupt 0 + DCD EINT1_IRQHandler ; 35: External Interrupt 1 + DCD EINT2_IRQHandler ; 36: External Interrupt 2 + DCD EINT3_IRQHandler ; 37: External Interrupt 3 + DCD ADC_IRQHandler ; 38: A/D Converter + DCD BOD_IRQHandler ; 39: Brown-Out Detect + DCD USB_IRQHandler ; 40: USB + DCD CAN_IRQHandler ; 41: CAN + DCD DMA_IRQHandler ; 42: General Purpose DMA + DCD I2S_IRQHandler ; 43: I2S + DCD ENET_IRQHandler ; 44: Ethernet + DCD MCI_IRQHandler ; 45: MCI Card + DCD MCPWM_IRQHandler ; 46: Motor Control PWM + DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface + DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL) + DCD USBActivity_IRQHandler ; 49: USB Activity Interrupt + DCD CANActivity_IRQHandler ; 50: CAN Activity Interrupt + DCD UART4_IRQHandler ; 51: UART4 + DCD SSP2_IRQHandler ; 52: SSP2 + DCD LCD_IRQHandler ; 53: LCD + DCD GPIO_IRQHandler ; 54: GPIO + DCD PWM0_IRQHandler ; 55: PWM0 + DCD EEPROM_IRQHandler ; 56: EEPROM + + + + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + PUBLIC CRP_Value + RSEG CRPKEY : CODE(2) +CRP_Value + DCD 0xFFFFFFFF +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER(1) +WDT_IRQHandler + B WDT_IRQHandler + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER0_IRQHandler + B TIMER0_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER3_IRQHandler + B TIMER3_IRQHandler + + PUBWEAK UART0_IRQHandler + SECTION .text:CODE:REORDER(1) +UART0_IRQHandler + B UART0_IRQHandler + + PUBWEAK UART1_IRQHandler + SECTION .text:CODE:REORDER(1) +UART1_IRQHandler + B UART1_IRQHandler + + PUBWEAK UART2_IRQHandler + SECTION .text:CODE:REORDER(1) +UART2_IRQHandler + B UART2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER(1) +PWM1_IRQHandler + B PWM1_IRQHandler + + PUBWEAK I2C0_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C0_IRQHandler + B I2C0_IRQHandler + + PUBWEAK I2C1_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C1_IRQHandler + B I2C1_IRQHandler + + PUBWEAK I2C2_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C2_IRQHandler + B I2C2_IRQHandler + + ;PUBWEAK SPIFI_IRQHandler + ;SECTION .text:CODE:REORDER(1) +;SPIFI_IRQHandler + ;B SPIFI_IRQHandler + + PUBWEAK SSP0_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP0_IRQHandler + B SSP0_IRQHandler + + PUBWEAK SSP1_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP1_IRQHandler + B SSP1_IRQHandler + + PUBWEAK PLL0_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL0_IRQHandler + B PLL0_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK EINT0_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT0_IRQHandler + B EINT0_IRQHandler + + PUBWEAK EINT1_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT1_IRQHandler + B EINT1_IRQHandler + + PUBWEAK EINT2_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT2_IRQHandler + B EINT2_IRQHandler + + PUBWEAK EINT3_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT3_IRQHandler + B EINT3_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK BOD_IRQHandler + SECTION .text:CODE:REORDER(1) +BOD_IRQHandler + B BOD_IRQHandler + + PUBWEAK USB_IRQHandler + SECTION .text:CODE:REORDER(1) +USB_IRQHandler + B USB_IRQHandler + + PUBWEAK CAN_IRQHandler + SECTION .text:CODE:REORDER(1) +CAN_IRQHandler + B CAN_IRQHandler + + PUBWEAK DMA_IRQHandler + SECTION .text:CODE:REORDER(1) +DMA_IRQHandler + B DMA_IRQHandler + + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER(1) +I2S_IRQHandler + B I2S_IRQHandler + + PUBWEAK ENET_IRQHandler + SECTION .text:CODE:REORDER(1) +ENET_IRQHandler + B ENET_IRQHandler + + PUBWEAK MCI_IRQHandler + SECTION .text:CODE:REORDER(1) +MCI_IRQHandler + B MCI_IRQHandler + + PUBWEAK MCPWM_IRQHandler + SECTION .text:CODE:REORDER(1) +MCPWM_IRQHandler + B MCPWM_IRQHandler + + PUBWEAK QEI_IRQHandler + SECTION .text:CODE:REORDER(1) +QEI_IRQHandler + B QEI_IRQHandler + + PUBWEAK PLL1_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL1_IRQHandler + B PLL1_IRQHandler + + PUBWEAK USBActivity_IRQHandler + SECTION .text:CODE:REORDER(1) +USBActivity_IRQHandler + B USBActivity_IRQHandler + + PUBWEAK CANActivity_IRQHandler + SECTION .text:CODE:REORDER(1) +CANActivity_IRQHandler + B CANActivity_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK SSP2_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP2_IRQHandler + B SSP2_IRQHandler + + PUBWEAK LCD_IRQHandler + SECTION .text:CODE:REORDER(1) +LCD_IRQHandler + B LCD_IRQHandler + + PUBWEAK GPIO_IRQHandler + SECTION .text:CODE:REORDER(1) +GPIO_IRQHandler + B GPIO_IRQHandler + + PUBWEAK PWM0_IRQHandler + SECTION .text:CODE:REORDER(1) +PWM0_IRQHandler + B PWM0_IRQHandler + + PUBWEAK EEPROM_IRQHandler + SECTION .text:CODE:REORDER(1) +EEPROM_IRQHandler + B EEPROM_IRQHandler + + END diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC407x_8x_177x_8x.s b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC407x_8x_177x_8x.s new file mode 100644 index 0000000000000000000000000000000000000000..55f4be7484f7df042cb09d66e47875d0a61f7833 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC407x_8x_177x_8x.s @@ -0,0 +1,396 @@ +;/***************************************************************************** +; * @file: startup_LPC177x_8x.s +; * @purpose: CMSIS Cortex-M3 Core Device Startup File +; * for the NXP LPC17xx Device Series +; * @version: V1.03 +; * @date: 09. February 2010 +; *---------------------------------------------------------------------------- +; * +; * Copyright (C) 2010 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 + EXTERN SystemInit + 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 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD WDT_IRQHandler ; 16: Watchdog Timer + DCD TIMER0_IRQHandler ; 17: Timer0 + DCD TIMER1_IRQHandler ; 18: Timer1 + DCD TIMER2_IRQHandler ; 19: Timer2 + DCD TIMER3_IRQHandler ; 20: Timer3 + DCD UART0_IRQHandler ; 21: UART0 + DCD UART1_IRQHandler ; 22: UART1 + DCD UART2_IRQHandler ; 23: UART2 + DCD UART3_IRQHandler ; 24: UART3 + DCD PWM1_IRQHandler ; 25: PWM1 + DCD I2C0_IRQHandler ; 26: I2C0 + DCD I2C1_IRQHandler ; 27: I2C1 + DCD I2C2_IRQHandler ; 28: I2C2 + DCD 0 ; 29: reserved; not for SPIFI anymore + DCD SSP0_IRQHandler ; 30: SSP0 + DCD SSP1_IRQHandler ; 31: SSP1 + DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL) + DCD RTC_IRQHandler ; 33: Real Time Clock + DCD EINT0_IRQHandler ; 34: External Interrupt 0 + DCD EINT1_IRQHandler ; 35: External Interrupt 1 + DCD EINT2_IRQHandler ; 36: External Interrupt 2 + DCD EINT3_IRQHandler ; 37: External Interrupt 3 + DCD ADC_IRQHandler ; 38: A/D Converter + DCD BOD_IRQHandler ; 39: Brown-Out Detect + DCD USB_IRQHandler ; 40: USB + DCD CAN_IRQHandler ; 41: CAN + DCD DMA_IRQHandler ; 42: General Purpose DMA + DCD I2S_IRQHandler ; 43: I2S + DCD ENET_IRQHandler ; 44: Ethernet + DCD MCI_IRQHandler ; 45: MCI Card + DCD MCPWM_IRQHandler ; 46: Motor Control PWM + DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface + DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL) + DCD USBActivity_IRQHandler ; 49: USB Activity Interrupt + DCD CANActivity_IRQHandler ; 50: CAN Activity Interrupt + DCD UART4_IRQHandler ; 51: UART4 + DCD SSP2_IRQHandler ; 52: SSP2 + DCD LCD_IRQHandler ; 53: LCD + DCD GPIO_IRQHandler ; 54: GPIO + DCD PWM0_IRQHandler ; 55: PWM0 + DCD EEPROM_IRQHandler ; 56: EEPROM + + + + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + PUBLIC CRP_Value + RSEG CRPKEY : CODE(2) +CRP_Value + DCD 0xFFFFFFFF +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER(1) +WDT_IRQHandler + B WDT_IRQHandler + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER0_IRQHandler + B TIMER0_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:REORDER(1) +TIMER3_IRQHandler + B TIMER3_IRQHandler + + PUBWEAK UART0_IRQHandler + SECTION .text:CODE:REORDER(1) +UART0_IRQHandler + B UART0_IRQHandler + + PUBWEAK UART1_IRQHandler + SECTION .text:CODE:REORDER(1) +UART1_IRQHandler + B UART1_IRQHandler + + PUBWEAK UART2_IRQHandler + SECTION .text:CODE:REORDER(1) +UART2_IRQHandler + B UART2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER(1) +PWM1_IRQHandler + B PWM1_IRQHandler + + PUBWEAK I2C0_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C0_IRQHandler + B I2C0_IRQHandler + + PUBWEAK I2C1_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C1_IRQHandler + B I2C1_IRQHandler + + PUBWEAK I2C2_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C2_IRQHandler + B I2C2_IRQHandler + + ;PUBWEAK SPIFI_IRQHandler + ;SECTION .text:CODE:REORDER(1) +;SPIFI_IRQHandler + ;B SPIFI_IRQHandler + + PUBWEAK SSP0_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP0_IRQHandler + B SSP0_IRQHandler + + PUBWEAK SSP1_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP1_IRQHandler + B SSP1_IRQHandler + + PUBWEAK PLL0_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL0_IRQHandler + B PLL0_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK EINT0_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT0_IRQHandler + B EINT0_IRQHandler + + PUBWEAK EINT1_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT1_IRQHandler + B EINT1_IRQHandler + + PUBWEAK EINT2_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT2_IRQHandler + B EINT2_IRQHandler + + PUBWEAK EINT3_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT3_IRQHandler + B EINT3_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK BOD_IRQHandler + SECTION .text:CODE:REORDER(1) +BOD_IRQHandler + B BOD_IRQHandler + + PUBWEAK USB_IRQHandler + SECTION .text:CODE:REORDER(1) +USB_IRQHandler + B USB_IRQHandler + + PUBWEAK CAN_IRQHandler + SECTION .text:CODE:REORDER(1) +CAN_IRQHandler + B CAN_IRQHandler + + PUBWEAK DMA_IRQHandler + SECTION .text:CODE:REORDER(1) +DMA_IRQHandler + B DMA_IRQHandler + + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER(1) +I2S_IRQHandler + B I2S_IRQHandler + + PUBWEAK ENET_IRQHandler + SECTION .text:CODE:REORDER(1) +ENET_IRQHandler + B ENET_IRQHandler + + PUBWEAK MCI_IRQHandler + SECTION .text:CODE:REORDER(1) +MCI_IRQHandler + B MCI_IRQHandler + + PUBWEAK MCPWM_IRQHandler + SECTION .text:CODE:REORDER(1) +MCPWM_IRQHandler + B MCPWM_IRQHandler + + PUBWEAK QEI_IRQHandler + SECTION .text:CODE:REORDER(1) +QEI_IRQHandler + B QEI_IRQHandler + + PUBWEAK PLL1_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL1_IRQHandler + B PLL1_IRQHandler + + PUBWEAK USBActivity_IRQHandler + SECTION .text:CODE:REORDER(1) +USBActivity_IRQHandler + B USBActivity_IRQHandler + + PUBWEAK CANActivity_IRQHandler + SECTION .text:CODE:REORDER(1) +CANActivity_IRQHandler + B CANActivity_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK SSP2_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP2_IRQHandler + B SSP2_IRQHandler + + PUBWEAK LCD_IRQHandler + SECTION .text:CODE:REORDER(1) +LCD_IRQHandler + B LCD_IRQHandler + + PUBWEAK GPIO_IRQHandler + SECTION .text:CODE:REORDER(1) +GPIO_IRQHandler + B GPIO_IRQHandler + + PUBWEAK PWM0_IRQHandler + SECTION .text:CODE:REORDER(1) +PWM0_IRQHandler + B PWM0_IRQHandler + + PUBWEAK EEPROM_IRQHandler + SECTION .text:CODE:REORDER(1) +EEPROM_IRQHandler + B EEPROM_IRQHandler + + END diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC177x_8x.c b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC177x_8x.c new file mode 100644 index 0000000000000000000000000000000000000000..ee222aee7ed8bd49e56a66da974130b95a6dfdd9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC177x_8x.c @@ -0,0 +1,507 @@ +/********************************************************************** +* $Id$ system_LPC177x_8x.c 2011-06-02 +*//** +* @file system_LPC177x_8x.c +* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File +* for the NXP LPC177x_8x Device Series +* +* ARM Limited (ARM) is supplying this software for use with +* Cortex-M processor based microcontrollers. This file can be +* freely distributed within development tools that are supporting +* such ARM based processors. +* +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 "LPC177x_8x.h" +#include "system_LPC177x_8x.h" + +#define __CLK_DIV(x,y) (((y) == 0) ? 0: (x)/(y)) + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ +/*--------------------- Clock Configuration ---------------------------------- +// +// Clock Configuration +// System Controls and Status Register (SCS - address 0x400F C1A0) +// EMC Shift Control Bit +// Controls how addresses are output on the EMC address pins for static memories +// <0=> Static CS addresses match bus width; AD[1] = 0 for 32 bit, AD[0] = 0 for 16+32 bit (Bit 0 is 0) +// <1=> Static CS addresses start at LSB 0 regardless of memory width (Bit 0 is 1) +// +// EMC Reset Disable Bit +// If 0 (zero), all registers and functions of the EMC are initialized upon any reset condition +// If 1, EMC is still retained its state through a warm reset +// <0=> Both EMC resets are asserted when any type of chip reset event occurs (Bit 1 is 0) +// <1=> Portions of EMC will only be reset by POR or BOR event (Bit 1 is 1) +// +// EMC Burst Control +// Set to 1 to prevent multiple sequential accesses to memory via EMC static memory chip selects +// <0=> Burst enabled (Bit 2 is 0) +// <1=> Bust disbled (Bit 2 is 1) +// +// MCIPWR Active Level +// Selects the active level for the SD card interface signal SD_PWR +// <0=> SD_PWR is active low (inverted output of the SD Card interface block) (Bit 3 is 0) +// <1=> SD_PWR is active high (follows the output of the SD Card interface block) (Bit 3 is 1) +// +// Main Oscillator Range Select +// <0=> In Range 1 MHz to 20 MHz (Bit 4 is 0) +// <1=> In Range 15 MHz to 25 MHz (Bit 4 is 1) +// +// Main Oscillator enable +// 0 (zero) means disabled, 1 means enable +// +// Main Oscillator status (Read-Only) +// +// +// Clock Source Select Register (CLKSRCSEL - address 0x400F C10C) +// CLKSRC: Select the clock source for sysclk to PLL0 clock +// <0=> Internal RC oscillator (Bit 0 is 0) +// <1=> Main oscillator (Bit 0 is 1) +// +// +// PLL0 Configuration (Main PLL PLL0CFG - address 0x400F C084) +// F_in is in the range of 1 MHz to 25 MHz +// F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz +// PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz +// +// MSEL: PLL Multiplier Value +// M Value +// <1-32><#-1> +// +// PSEL: PLL Divider Value +// P Value +// <0=> 1 +// <1=> 2 +// <2=> 4 +// <3=> 8 +// +// +// PLL1 Configuration (Alt PLL PLL1CFG - address 0x400F C0A4) +// F_in is in the range of 1 MHz to 25 MHz +// F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz +// PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz +// +// MSEL: PLL Multiplier Value +// M Value +// <1-32><#-1> +// +// PSEL: PLL Divider Value +// P Value +// <0=> 1 +// <1=> 2 +// <2=> 4 +// <3=> 8 +// +// +// CPU Clock Selection Register (CCLKSEL - address 0x400F C104) +// CCLKDIV: Select the value for divider of CPU clock (CCLK) +// 0: The divider is turned off. No clock will be provided to the CPU +// n: The input clock is divided by n to produce the CPU clock +// <0-31> +// +// CCLKSEL: Select the input to the divider of CPU clock +// <0=> sysclk clock is used +// <1=> Main PLL0 clock is used +// +// +// USB Clock Selection Register (USBCLKSEL - 0x400F C108) +// USBDIV: USB clock (source PLL0) divider selection +// <0=> Divider is off and no clock provides to USB subsystem +// <4=> Divider value is 4 (The source clock is divided by 4) +// <6=> Divider value is 6 (The source clock is divided by 6) +// +// USBSEL: Select the source for USB clock divider +// When CPU clock is selected, the USB can be accessed +// by software but cannot perform USB functions +// <0=> sysclk clock (the clock input to PLL0) +// <1=> The clock output from PLL0 +// <2=> The clock output from PLL1 +// +// +// EMC Clock Selection Register (EMCCLKSEL - address 0x400F C100) +// EMCDIV: Set the divider for EMC clock +// <0=> Divider value is 1 +// <1=> Divider value is 2 (EMC clock is equal a half of input clock) +// +// +// Peripheral Clock Selection Register (PCLKSEL - address 0x400F C1A8) +// PCLKDIV: APB Peripheral clock divider +// 0: The divider is turned off. No clock will be provided to APB peripherals +// n: The input clock is divided by n to produce the APB peripheral clock +// <0-31> +// +// +// Power Control for Peripherals Register (PCONP - address 0x400F C1C8) +// PCLCD: LCD controller power/clock enable (bit 0) +// PCTIM0: Timer/Counter 0 power/clock enable (bit 1) +// PCTIM1: Timer/Counter 1 power/clock enable (bit 2) +// PCUART0: UART 0 power/clock enable (bit 3) +// PCUART1: UART 1 power/clock enable (bit 4) +// PCPWM0: PWM0 power/clock enable (bit 5) +// PCPWM1: PWM1 power/clock enable (bit 6) +// PCI2C0: I2C 0 interface power/clock enable (bit 7) +// PCUART4: UART 4 power/clock enable (bit 8) +// PCRTC: RTC and Event Recorder power/clock enable (bit 9) +// PCSSP1: SSP 1 interface power/clock enable (bit 10) +// PCEMC: External Memory Controller power/clock enable (bit 11) +// PCADC: A/D converter power/clock enable (bit 12) +// PCCAN1: CAN controller 1 power/clock enable (bit 13) +// PCCAN2: CAN controller 2 power/clock enable (bit 14) +// PCGPIO: IOCON, GPIO, and GPIO interrupts power/clock enable (bit 15) +// PCMCPWM: Motor Control PWM power/clock enable (bit 17) +// PCQEI: Quadrature encoder interface power/clock enable (bit 18) +// PCI2C1: I2C 1 interface power/clock enable (bit 19) +// PCSSP2: SSP 2 interface power/clock enable (bit 20) +// PCSSP0: SSP 0 interface power/clock enable (bit 21) +// PCTIM2: Timer 2 power/clock enable (bit 22) +// PCTIM3: Timer 3 power/clock enable (bit 23) +// PCUART2: UART 2 power/clock enable (bit 24) +// PCUART3: UART 3 power/clock enable (bit 25) +// PCI2C2: I2C 2 interface power/clock enable (bit 26) +// PCI2S: I2S interface power/clock enable (bit 27) +// PCSDC: SD Card interface power/clock enable (bit 28) +// PCGPDMA: GPDMA function power/clock enable (bit 29) +// PCENET: Ethernet block power/clock enable (bit 30) +// PCUSB: USB interface power/clock enable (bit 31) +// +// +// Clock Output Configuration Register (CLKOUTCFG) +// CLKOUTSEL: Clock Source for CLKOUT Selection +// <0=> CPU clock +// <1=> Main Oscillator +// <2=> Internal RC Oscillator +// <3=> USB clock +// <4=> RTC Oscillator +// <5=> unused +// <6=> Watchdog Oscillator +// +// CLKOUTDIV: Output Clock Divider +// <1-16><#-1> +// +// CLKOUT_EN: CLKOUT enable +// +// +// +*/ + +#define CLOCK_SETUP 1 +#define SCS_Val 0x00000021 +#define CLKSRCSEL_Val 0x00000001 +#define PLL0_SETUP 1 +#define PLL0CFG_Val 0x00000009 +#define PLL1_SETUP 1 +#define PLL1CFG_Val 0x00000023 +#define CCLKSEL_Val 0x00000101 +#define USBCLKSEL_Val 0x00000201 +#define EMCCLKSEL_Val 0x00000001 +#define PCLKSEL_Val 0x00000002 +#define PCONP_Val 0x042887DE +#define CLKOUTCFG_Val 0x00000100 + + +/*--------------------- Flash Accelerator Configuration ---------------------- +// +// Flash Accelerator Configuration register (FLASHCFG - address 0x400F C000) +// FLASHTIM: Flash Access Time +// <0=> 1 CPU clock (for CPU clock up to 20 MHz) +// <1=> 2 CPU clocks (for CPU clock up to 40 MHz) +// <2=> 3 CPU clocks (for CPU clock up to 60 MHz) +// <3=> 4 CPU clocks (for CPU clock up to 80 MHz) +// <4=> 5 CPU clocks (for CPU clock up to 100 MHz) +// <5=> 6 CPU clocks (for any CPU clock) +// +*/ + +#define FLASH_SETUP 1 +#define FLASHCFG_Val 0x00005000 + +/*---------------------------------------------------------------------------- + Check the register settings + *----------------------------------------------------------------------------*/ +#define CHECK_RANGE(val, min, max) ((val < min) || (val > max)) +#define CHECK_RSVD(val, mask) (val & mask) + +/* Clock Configuration -------------------------------------------------------*/ +#if (CHECK_RSVD((SCS_Val), ~0x0000003F)) + #error "SCS: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 1)) + #error "CLKSRCSEL: Value out of range!" +#endif + +#if (CHECK_RSVD((PLL0CFG_Val), ~0x0000007F)) + #error "PLL0CFG: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F)) + #error "PLL1CFG: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((CCLKSEL_Val), ~0x0000011F)) + #error "CCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((USBCLKSEL_Val), ~0x0000031F)) + #error "USBCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((EMCCLKSEL_Val), ~0x00000001)) + #error "EMCCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PCLKSEL_Val), ~0x0000001F)) + #error "PCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PCONP_Val), ~0xFFFEFFFF)) + #error "PCONP: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF)) + #error "CLKOUTCFG: Invalid values of reserved bits!" +#endif + +/* Flash Accelerator Configuration -------------------------------------------*/ +#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000)) + #warning "FLASHCFG: Invalid values of reserved bits!" +#endif + + +/*---------------------------------------------------------------------------- + DEFINES + *----------------------------------------------------------------------------*/ +/* pll_out_clk = F_cco / (2 × P) + F_cco = pll_in_clk × M × 2 × P */ +#define __M ((PLL0CFG_Val & 0x1F) + 1) +#define __PLL0_CLK(__F_IN) (__F_IN * __M) +#define __CCLK_DIV (CCLKSEL_Val & 0x1F) +#define __PCLK_DIV (PCLKSEL_Val & 0x1F) +#define __ECLK_DIV ((EMCCLKSEL_Val & 0x01) + 1) + +/* Determine core clock frequency according to settings */ +#if (CLOCK_SETUP) /* Clock Setup */ + + #if ((CLKSRCSEL_Val & 0x01) == 1) && ((SCS_Val & 0x20)== 0) + #error "Main Oscillator is selected as clock source but is not enabled!" + #endif + + #if ((CCLKSEL_Val & 0x100) == 0x100) && (PLL0_SETUP == 0) + #error "Main PLL is selected as clock source but is not enabled!" + #endif + + #if ((CCLKSEL_Val & 0x100) == 0) /* cclk = sysclk */ + #if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */ + #define __CORE_CLK (IRC_OSC / __CCLK_DIV) + #define __PER_CLK (IRC_OSC/ __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK/ __ECLK_DIV) + #else /* sysclk = osc_clk */ + #define __CORE_CLK (OSC_CLK / __CCLK_DIV) + #define __PER_CLK (OSC_CLK/ __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK/ __ECLK_DIV) + #endif + #else /* cclk = pll_clk */ + #if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */ + #define __CORE_CLK (__PLL0_CLK(IRC_OSC) / __CCLK_DIV) + #define __PER_CLK (__PLL0_CLK(IRC_OSC) / __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK / __ECLK_DIV) + #else /* sysclk = osc_clk */ + #define __CORE_CLK (__PLL0_CLK(OSC_CLK) / __CCLK_DIV) + #define __PER_CLK (__PLL0_CLK(OSC_CLK) / __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK / __ECLK_DIV) + #endif + #endif + +#else + #define __CORE_CLK (IRC_OSC) + #define __PER_CLK (IRC_OSC) + #define __EMC_CLK (__CORE_CLK) +#endif + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/ +uint32_t PeripheralClock = __PER_CLK; /*!< Peripheral Clock Frequency (Pclk) */ +uint32_t EMCClock = __EMC_CLK; /*!< EMC Clock Frequency */ +uint32_t USBClock = (48000000UL); /*!< USB Clock Frequency - this value will + be updated after call SystemCoreClockUpdate, should be 48MHz*/ + + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ + /* Determine clock frequency according to clock register values */ + if ((LPC_SC->CCLKSEL &0x100) == 0) { /* cclk = sysclk */ + if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */ + SystemCoreClock = __CLK_DIV(IRC_OSC , (LPC_SC->CCLKSEL & 0x1F)); + PeripheralClock = __CLK_DIV(IRC_OSC , (LPC_SC->PCLKSEL & 0x1F)); + EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1)); + } + else { /* sysclk = osc_clk */ + if ((LPC_SC->SCS & 0x40) == 0) { + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + SystemCoreClock = __CLK_DIV(OSC_CLK , (LPC_SC->CCLKSEL & 0x1F)); + PeripheralClock = __CLK_DIV(OSC_CLK , (LPC_SC->PCLKSEL & 0x1F)); + EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1)); + } + } + } + else { /* cclk = pll_clk */ + if ((LPC_SC->PLL0STAT & 0x100) == 0) { /* PLL0 not enabled */ + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */ + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F); + uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F); + uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1; + SystemCoreClock = __CLK_DIV(IRC_OSC * mul , cpu_div); + PeripheralClock = __CLK_DIV(IRC_OSC * mul , per_div); + EMCClock = SystemCoreClock / emc_div; + } + else { /* sysclk = osc_clk */ + if ((LPC_SC->SCS & 0x40) == 0) { + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F); + uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F); + uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1; + SystemCoreClock = __CLK_DIV(OSC_CLK * mul , cpu_div); + PeripheralClock = __CLK_DIV(OSC_CLK * mul , per_div); + EMCClock = SystemCoreClock / emc_div; + } + } + } + } + /* ---update USBClock------------------*/ + if(LPC_SC->USBCLKSEL & (0x01<<8))//Use PLL0 as the input to the USB clock divider + { + switch (LPC_SC->USBCLKSEL & 0x1F) + { + case 0: + USBClock = 0; //no clock will be provided to the USB subsystem + break; + case 4: + case 6: + { + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t usb_div = (LPC_SC->USBCLKSEL & 0x1F); + if(LPC_SC->CLKSRCSEL & 0x01) //pll_clk_in = main_osc + USBClock = OSC_CLK * mul / usb_div; + else //pll_clk_in = irc_clk + USBClock = IRC_OSC * mul / usb_div; + } + break; + default: + USBClock = 0; /* this should never happen! */ + } + } + else if(LPC_SC->USBCLKSEL & (0x02<<8))//usb_input_clk = alt_pll (pll1) + { + if(LPC_SC->CLKSRCSEL & 0x01) //pll1_clk_in = main_osc + USBClock = (OSC_CLK * ((LPC_SC->PLL1STAT & 0x1F) + 1)); + else //pll1_clk_in = irc_clk + USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1)); + } + else + USBClock = 0; /* this should never happen! */ +} + + /* Determine clock frequency according to clock register values */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit (void) +{ +#if (CLOCK_SETUP) /* Clock Setup */ + LPC_SC->SCS = SCS_Val; + if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */ + while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */ + } + + LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for sysclk/PLL0*/ + +#if (PLL0_SETUP) + LPC_SC->PLL0CFG = PLL0CFG_Val; + LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + while (!(LPC_SC->PLL0STAT & (1<<10)));/* Wait for PLOCK0 */ +#endif + +#if (PLL1_SETUP) + LPC_SC->PLL1CFG = PLL1CFG_Val; + LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */ + LPC_SC->PLL1FEED = 0xAA; + LPC_SC->PLL1FEED = 0x55; + while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */ +#endif + + LPC_SC->CCLKSEL = CCLKSEL_Val; /* Setup Clock Divider */ + LPC_SC->USBCLKSEL = USBCLKSEL_Val; /* Setup USB Clock Divider */ + LPC_SC->EMCCLKSEL = EMCCLKSEL_Val; /* EMC Clock Selection */ + LPC_SC->PCLKSEL = PCLKSEL_Val; /* Peripheral Clock Selection */ + LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */ + LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */ +#endif + + LPC_SC->PBOOST |= 0x03; /* Power Boost control */ + +#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */ + LPC_SC->FLASHCFG = FLASHCFG_Val|0x03A; +#endif +#ifdef __RAM_MODE__ + SCB->VTOR = 0x10000000 & 0x3FFFFF80; +#else + SCB->VTOR = 0x00000000 & 0x3FFFFF80; +#endif + SystemCoreClockUpdate(); +} diff --git a/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c new file mode 100644 index 0000000000000000000000000000000000000000..d85871526efa46505bafb9ae20c7448e6aeab876 --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c @@ -0,0 +1,571 @@ +/********************************************************************** +* $Id$ system_LPC407x_8x_177x_8x.c 2012-01-16 +*//** +* @file system_LPC407x_8x_177x_8x.c +* @brief CMSIS Cortex-M3, M4 Device Peripheral Access Layer Source File +* for the NXP LPC407x_8x_177x_8x Device Series +* +* ARM Limited (ARM) is supplying this software for use with +* Cortex-M processor based microcontrollers. This file can be +* freely distributed within development tools that are supporting +* such ARM based processors. +* +* @version 1.2 +* @date 20. June. 2012 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2012, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#include +#include "LPC407x_8x_177x_8x.h" +#include "system_LPC407x_8x_177x_8x.h" + +#define __CLK_DIV(x,y) (((y) == 0) ? 0: (x)/(y)) + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ +/*--------------------- Clock Configuration ---------------------------------- +// +// Clock Configuration +// System Controls and Status Register (SCS - address 0x400F C1A0) +// EMC Shift Control Bit +// Controls how addresses are output on the EMC address pins for static memories +// <0=> Static CS addresses match bus width; AD[1] = 0 for 32 bit, AD[0] = 0 for 16+32 bit (Bit 0 is 0) +// <1=> Static CS addresses start at LSB 0 regardless of memory width (Bit 0 is 1) +// +// EMC Reset Disable Bit +// If 0 (zero), all registers and functions of the EMC are initialized upon any reset condition +// If 1, EMC is still retained its state through a warm reset +// <0=> Both EMC resets are asserted when any type of chip reset event occurs (Bit 1 is 0) +// <1=> Portions of EMC will only be reset by POR or BOR event (Bit 1 is 1) +// +// EMC Burst Control +// Set to 1 to prevent multiple sequential accesses to memory via EMC static memory chip selects +// <0=> Burst enabled (Bit 2 is 0) +// <1=> Bust disbled (Bit 2 is 1) +// +// MCIPWR Active Level +// Selects the active level for the SD card interface signal SD_PWR +// <0=> SD_PWR is active low (inverted output of the SD Card interface block) (Bit 3 is 0) +// <1=> SD_PWR is active high (follows the output of the SD Card interface block) (Bit 3 is 1) +// +// Main Oscillator Range Select +// <0=> In Range 1 MHz to 20 MHz (Bit 4 is 0) +// <1=> In Range 15 MHz to 25 MHz (Bit 4 is 1) +// +// Main Oscillator enable +// 0 (zero) means disabled, 1 means enable +// +// Main Oscillator status (Read-Only) +// +// +// Clock Source Select Register (CLKSRCSEL - address 0x400F C10C) +// CLKSRC: Select the clock source for sysclk to PLL0 clock +// <0=> Internal RC oscillator (Bit 0 is 0) +// <1=> Main oscillator (Bit 0 is 1) +// +// +// PLL0 Configuration (Main PLL PLL0CFG - address 0x400F C084) +// F_in is in the range of 1 MHz to 25 MHz +// F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz +// PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz +// +// MSEL: PLL Multiplier Value +// M Value +// <1-32><#-1> +// +// PSEL: PLL Divider Value +// P Value +// <0=> 1 +// <1=> 2 +// <2=> 4 +// <3=> 8 +// +// +// PLL1 Configuration (Alt PLL PLL1CFG - address 0x400F C0A4) +// F_in is in the range of 1 MHz to 25 MHz +// F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz +// PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz +// +// MSEL: PLL Multiplier Value +// M Value +// <1-32><#-1> +// +// PSEL: PLL Divider Value +// P Value +// <0=> 1 +// <1=> 2 +// <2=> 4 +// <3=> 8 +// +// +// CPU Clock Selection Register (CCLKSEL - address 0x400F C104) +// CCLKDIV: Select the value for divider of CPU clock (CCLK) +// 0: The divider is turned off. No clock will be provided to the CPU +// n: The input clock is divided by n to produce the CPU clock +// <0-31> +// +// CCLKSEL: Select the input to the divider of CPU clock +// <0=> sysclk clock is used +// <1=> Main PLL0 clock is used +// +// +// USB Clock Selection Register (USBCLKSEL - 0x400F C108) +// USBDIV: USB clock (source PLL0) divider selection +// <0=> Divider is off and no clock provides to USB subsystem +// <4=> Divider value is 4 (The source clock is divided by 4) +// <6=> Divider value is 6 (The source clock is divided by 6) +// +// USBSEL: Select the source for USB clock divider +// When CPU clock is selected, the USB can be accessed +// by software but cannot perform USB functions +// <0=> sysclk clock (the clock input to PLL0) +// <1=> The clock output from PLL0 +// <2=> The clock output from PLL1 +// +// +// EMC Clock Selection Register (EMCCLKSEL - address 0x400F C100) +// EMCDIV: Set the divider for EMC clock +// <0=> Divider value is 1 +// <1=> Divider value is 2 (EMC clock is equal a half of input clock) +// +// +// Peripheral Clock Selection Register (PCLKSEL - address 0x400F C1A8) +// PCLKDIV: APB Peripheral clock divider +// 0: The divider is turned off. No clock will be provided to APB peripherals +// n: The input clock is divided by n to produce the APB peripheral clock +// <0-31> +// +// +// SPIFI Clock Selection Register (SPIFICLKSEL - address 0x400F C1B4) +// SPIFIDIV: Set the divider for SPIFI clock +// 0: The divider is turned off. No clock will be provided to the SPIFI +// n: The input clock is divided by n to produce the SPIFI clock +// <0-31> +// +// SPIFISEL: Select the input clock for SPIFI clock divider +// <0=> sysclk clock (the clock input to PLL0) +// <1=> The clock output from PLL0 +// <2=> The clock output from PLL1 +// +// +// Power Control for Peripherals Register (PCONP - address 0x400F C1C8) +// PCLCD: LCD controller power/clock enable (bit 0) +// PCTIM0: Timer/Counter 0 power/clock enable (bit 1) +// PCTIM1: Timer/Counter 1 power/clock enable (bit 2) +// PCUART0: UART 0 power/clock enable (bit 3) +// PCUART1: UART 1 power/clock enable (bit 4) +// PCPWM0: PWM0 power/clock enable (bit 5) +// PCPWM1: PWM1 power/clock enable (bit 6) +// PCI2C0: I2C 0 interface power/clock enable (bit 7) +// PCUART4: UART 4 power/clock enable (bit 8) +// PCRTC: RTC and Event Recorder power/clock enable (bit 9) +// PCSSP1: SSP 1 interface power/clock enable (bit 10) +// PCEMC: External Memory Controller power/clock enable (bit 11) +// PCADC: A/D converter power/clock enable (bit 12) +// PCCAN1: CAN controller 1 power/clock enable (bit 13) +// PCCAN2: CAN controller 2 power/clock enable (bit 14) +// PCGPIO: IOCON, GPIO, and GPIO interrupts power/clock enable (bit 15) +// PCMCPWM: Motor Control PWM power/clock enable (bit 17) +// PCQEI: Quadrature encoder interface power/clock enable (bit 18) +// PCI2C1: I2C 1 interface power/clock enable (bit 19) +// PCSSP2: SSP 2 interface power/clock enable (bit 20) +// PCSSP0: SSP 0 interface power/clock enable (bit 21) +// PCTIM2: Timer 2 power/clock enable (bit 22) +// PCTIM3: Timer 3 power/clock enable (bit 23) +// PCUART2: UART 2 power/clock enable (bit 24) +// PCUART3: UART 3 power/clock enable (bit 25) +// PCI2C2: I2C 2 interface power/clock enable (bit 26) +// PCI2S: I2S interface power/clock enable (bit 27) +// PCSDC: SD Card interface power/clock enable (bit 28) +// PCGPDMA: GPDMA function power/clock enable (bit 29) +// PCENET: Ethernet block power/clock enable (bit 30) +// PCUSB: USB interface power/clock enable (bit 31) +// +// +// Clock Output Configuration Register (CLKOUTCFG) +// CLKOUTSEL: Clock Source for CLKOUT Selection +// <0=> CPU clock +// <1=> Main Oscillator +// <2=> Internal RC Oscillator +// <3=> USB clock +// <4=> RTC Oscillator +// <5=> unused +// <6=> Watchdog Oscillator +// +// CLKOUTDIV: Output Clock Divider +// <1-16><#-1> +// +// CLKOUT_EN: CLKOUT enable +// +// +// +*/ + +#define CLOCK_SETUP 1 +#define SCS_Val 0x00000020 +#define CLKSRCSEL_Val 0x00000001 +#define PLL0_SETUP 1 +#define PLL0CFG_Val 0x0000000a +#define PLL1_SETUP 1 +#define PLL1CFG_Val 0x00000023 +#define CCLKSEL_Val 0x00000101 +#define USBCLKSEL_Val 0x00000201 +#define EMCCLKSEL_Val 0x00000001 +#define PCLKSEL_Val 0x00000002 +#define SPIFICLKSEL_Val 0x00000002 +#define PCONP_Val 0x042887DE +#define CLKOUTCFG_Val 0x00000100 + +#ifdef CORE_M4 +#define LPC_CPACR 0xE000ED88 + +#define SCB_MVFR0 0xE000EF40 +#define SCB_MVFR0_RESET 0x10110021 + +#define SCB_MVFR1 0xE000EF44 +#define SCB_MVFR1_RESET 0x11000011 +#endif + + +/*--------------------- Flash Accelerator Configuration ---------------------- +// +// Flash Accelerator Configuration register (FLASHCFG - address 0x400F C000) +// FLASHTIM: Flash Access Time +// <0=> 1 CPU clock (for CPU clock up to 20 MHz) +// <1=> 2 CPU clocks (for CPU clock up to 40 MHz) +// <2=> 3 CPU clocks (for CPU clock up to 60 MHz) +// <3=> 4 CPU clocks (for CPU clock up to 80 MHz) +// <4=> 5 CPU clocks (for CPU clock up to 100 MHz) +// <5=> 6 CPU clocks (for any CPU clock) +// +*/ + +#define FLASH_SETUP 1 +#define FLASHCFG_Val 0x00005000 + +/*---------------------------------------------------------------------------- + Check the register settings + *----------------------------------------------------------------------------*/ +#define CHECK_RANGE(val, min, max) ((val < min) || (val > max)) +#define CHECK_RSVD(val, mask) (val & mask) + +/* Clock Configuration -------------------------------------------------------*/ +#if (CHECK_RSVD((SCS_Val), ~0x0000003F)) + #error "SCS: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 1)) + #error "CLKSRCSEL: Value out of range!" +#endif + +#if (CHECK_RSVD((PLL0CFG_Val), ~0x0000007F)) + #error "PLL0CFG: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F)) + #error "PLL1CFG: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((CCLKSEL_Val), ~0x0000011F)) + #error "CCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((USBCLKSEL_Val), ~0x0000031F)) + #error "USBCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((EMCCLKSEL_Val), ~0x00000001)) + #error "EMCCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PCLKSEL_Val), ~0x0000001F)) + #error "PCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((PCONP_Val), ~0xFFFEFFFF)) + #error "PCONP: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF)) + #error "CLKOUTCFG: Invalid values of reserved bits!" +#endif + +/* Flash Accelerator Configuration -------------------------------------------*/ +#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000)) + #error "FLASHCFG: Invalid values of reserved bits!" +#endif + + +/*---------------------------------------------------------------------------- + DEFINES + *----------------------------------------------------------------------------*/ +/* pll_out_clk = F_cco / (2 ?P) + F_cco = pll_in_clk ?M ?2 ?P */ +#define __M ((PLL0CFG_Val & 0x1F) + 1) +#define __PLL0_CLK(__F_IN) (__F_IN * __M) +#define __CCLK_DIV (CCLKSEL_Val & 0x1F) +#define __PCLK_DIV (PCLKSEL_Val & 0x1F) +#define __ECLK_DIV ((EMCCLKSEL_Val & 0x01) + 1) + +/* Determine core clock frequency according to settings */ +#if (CLOCK_SETUP) /* Clock Setup */ + + #if ((CLKSRCSEL_Val & 0x01) == 1) && ((SCS_Val & 0x20)== 0) + #error "Main Oscillator is selected as clock source but is not enabled!" + #endif + + #if ((CCLKSEL_Val & 0x100) == 0x100) && (PLL0_SETUP == 0) + #error "Main PLL is selected as clock source but is not enabled!" + #endif + + #if ((CCLKSEL_Val & 0x100) == 0) /* cclk = sysclk */ + #if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */ + #define __CORE_CLK (IRC_OSC / __CCLK_DIV) + #define __PER_CLK (IRC_OSC/ __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK/ __ECLK_DIV) + #else /* sysclk = osc_clk */ + #define __CORE_CLK (OSC_CLK / __CCLK_DIV) + #define __PER_CLK (OSC_CLK/ __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK/ __ECLK_DIV) + #endif + #else /* cclk = pll_clk */ + #if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */ + #define __CORE_CLK (__PLL0_CLK(IRC_OSC) / __CCLK_DIV) + #define __PER_CLK (__PLL0_CLK(IRC_OSC) / __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK / __ECLK_DIV) + #else /* sysclk = osc_clk */ + #define __CORE_CLK (__PLL0_CLK(OSC_CLK) / __CCLK_DIV) + #define __PER_CLK (__PLL0_CLK(OSC_CLK) / __PCLK_DIV) + #define __EMC_CLK (__CORE_CLK / __ECLK_DIV) + #endif + #endif + +#else + #define __CORE_CLK (IRC_OSC) + #define __PER_CLK (IRC_OSC) + #define __EMC_CLK (__CORE_CLK) +#endif + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/ +uint32_t PeripheralClock = __PER_CLK; /*!< Peripheral Clock Frequency (Pclk) */ +uint32_t EMCClock = __EMC_CLK; /*!< EMC Clock Frequency */ +uint32_t USBClock = (48000000UL); /*!< USB Clock Frequency - this value will + be updated after call SystemCoreClockUpdate, should be 48MHz*/ + + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ + /* Determine clock frequency according to clock register values */ + if ((LPC_SC->CCLKSEL &0x100) == 0) { /* cclk = sysclk */ + if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */ + SystemCoreClock = __CLK_DIV(IRC_OSC , (LPC_SC->CCLKSEL & 0x1F)); + PeripheralClock = __CLK_DIV(IRC_OSC , (LPC_SC->PCLKSEL & 0x1F)); + EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1)); + } + else { /* sysclk = osc_clk */ + if ((LPC_SC->SCS & 0x40) == 0) { + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + SystemCoreClock = __CLK_DIV(OSC_CLK , (LPC_SC->CCLKSEL & 0x1F)); + PeripheralClock = __CLK_DIV(OSC_CLK , (LPC_SC->PCLKSEL & 0x1F)); + EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1)); + } + } + } + else { /* cclk = pll_clk */ + if ((LPC_SC->PLL0STAT & 0x100) == 0) { /* PLL0 not enabled */ + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */ + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F); + uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F); + uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1; + SystemCoreClock = __CLK_DIV(IRC_OSC * mul , cpu_div); + PeripheralClock = __CLK_DIV(IRC_OSC * mul , per_div); + EMCClock = SystemCoreClock / emc_div; + } + else { /* sysclk = osc_clk */ + if ((LPC_SC->SCS & 0x40) == 0) { + SystemCoreClock = 0; /* this should never happen! */ + PeripheralClock = 0; + EMCClock = 0; + } + else { + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F); + uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F); + uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1; + SystemCoreClock = __CLK_DIV(OSC_CLK * mul , cpu_div); + PeripheralClock = __CLK_DIV(OSC_CLK * mul , per_div); + EMCClock = SystemCoreClock / emc_div; + } + } + } + } + /* ---update USBClock------------------*/ + if(LPC_SC->USBCLKSEL & (0x01<<8))//Use PLL0 as the input to the USB clock divider + { + switch (LPC_SC->USBCLKSEL & 0x1F) + { + case 0: + USBClock = 0; //no clock will be provided to the USB subsystem + break; + case 4: + case 6: + { + uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1); + uint8_t usb_div = (LPC_SC->USBCLKSEL & 0x1F); + if(LPC_SC->CLKSRCSEL & 0x01) //pll_clk_in = main_osc + USBClock = OSC_CLK * mul / usb_div; + else //pll_clk_in = irc_clk + USBClock = IRC_OSC * mul / usb_div; + } + break; + default: + USBClock = 0; /* this should never happen! */ + } + } + else if(LPC_SC->USBCLKSEL & (0x02<<8))//usb_input_clk = alt_pll (pll1) + { + if(LPC_SC->CLKSRCSEL & 0x01) //pll1_clk_in = main_osc + USBClock = (OSC_CLK * ((LPC_SC->PLL1STAT & 0x1F) + 1)); + else //pll1_clk_in = irc_clk + USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1)); + } + else + USBClock = 0; /* this should never happen! */ +} + + /* Determine clock frequency according to clock register values */ + +#ifdef CORE_M4 + +void fpu_init(void) +{ + // 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 + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit (void) +{ +#ifndef __CODE_RED +#ifdef CORE_M4 +fpu_init(); +#endif +#endif + +#if (CLOCK_SETUP) /* Clock Setup */ + LPC_SC->SCS = SCS_Val; + if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */ + while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */ + } + + LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for sysclk/PLL0*/ + +#if (PLL0_SETUP) + LPC_SC->PLL0CFG = PLL0CFG_Val; + LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + while (!(LPC_SC->PLL0STAT & (1<<10)));/* Wait for PLOCK0 */ +#endif + +#if (PLL1_SETUP) + LPC_SC->PLL1CFG = PLL1CFG_Val; + LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */ + LPC_SC->PLL1FEED = 0xAA; + LPC_SC->PLL1FEED = 0x55; + while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */ +#endif + + LPC_SC->CCLKSEL = CCLKSEL_Val; /* Setup Clock Divider */ + LPC_SC->USBCLKSEL = USBCLKSEL_Val; /* Setup USB Clock Divider */ + LPC_SC->EMCCLKSEL = EMCCLKSEL_Val; /* EMC Clock Selection */ + LPC_SC->SPIFICLKSEL = SPIFICLKSEL_Val; /* SPIFI Clock Selection */ + LPC_SC->PCLKSEL = PCLKSEL_Val; /* Peripheral Clock Selection */ + LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */ + LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */ +#endif + + LPC_SC->PBOOST |= 0x03; /* Power Boost control */ + +#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */ + LPC_SC->FLASHCFG = FLASHCFG_Val|0x03A; +#endif +#ifndef __CODE_RED +#ifdef __RAM_MODE__ + SCB->VTOR = 0x10000000 & 0x3FFFFF80; +#else + SCB->VTOR = 0x00000000 & 0x3FFFFF80; +#endif +#endif + SystemCoreClockUpdate(); +} diff --git a/bsp/lpc408x/Libraries/Device/SConscript b/bsp/lpc408x/Libraries/Device/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..f61ac45490a753e7e0ed27ad06aa4b3ff813c95d --- /dev/null +++ b/bsp/lpc408x/Libraries/Device/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c +''') +CPPPATH = [cwd + '/NXP/LPC407x_8x_177x_8x/Include', cwd + '/../CMSIS/Include'] +CPPDEFINES = ['CORE_M4'] + +# add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + src += ['NXP/LPC407x_8x_177x_8x/Source/Templates/GCC/startup_LPC407x_8x_177x_8x.s'] +elif rtconfig.CROSS_TOOL == 'keil': + src += ['NXP/LPC407x_8x_177x_8x/Source/Templates/ARM/startup_LPC407x_8x_177x_8x.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += ['NXP/LPC407x_8x_177x_8x/Source/Templates/IAR/startup_LPC407x_8x_177x_8x.s'] + +group = DefineGroup('CMSIS', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/lpc408x/Libraries/Drivers/SConscript b/bsp/lpc408x/Libraries/Drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ed77a5ca4fae57848ceca231d6bf9e1d6e53fe9f --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/SConscript @@ -0,0 +1,39 @@ +# RT-Thread building script for component + +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +source/lpc_adc.c +source/lpc_bod.c +source/lpc_can.c +source/lpc_clkpwr.c +source/lpc_crc.c +source/lpc_dac.c +source/lpc_eeprom.c +source/lpc_emc.c +source/lpc_exti.c +source/lpc_gpdma.c +source/lpc_gpio.c +source/lpc_i2c.c +source/lpc_i2s.c +source/lpc_iap.c +source/lpc_lcd.c +source/lpc_mcpwm.c +source/lpc_nvic.c +source/lpc_pinsel.c +source/lpc_pwm.c +source/lpc_qei.c +source/lpc_rtc.c +source/lpc_ssp.c +source/lpc_systick.c +source/lpc_timer.c +source/lpc_uart.c +source/lpc_wwdt.c +''') +CPPPATH = [cwd + '/include'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/lpc408x/Libraries/Drivers/include/debug_frmwrk.h b/bsp/lpc408x/Libraries/Drivers/include/debug_frmwrk.h new file mode 100644 index 0000000000000000000000000000000000000000..dc6bd823a9048049d792b89ee5d2980ec8c45268 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/debug_frmwrk.h @@ -0,0 +1,114 @@ +/********************************************************************** +* $Id$ debug_frmwrk.h 2011-06-02 +*//** +* @file debug_frmwrk.h +* @brief Contains some utilities that used for debugging through UART +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 __DEBUG_FRMWRK_H_ +#define __DEBUG_FRMWRK_H_ + +#include "lpc_uart.h" + +#define USED_UART_DEBUG_PORT 0 + +#define NUM_SKIPPED_ALLOWED (10) + +#define DBG_GETVAL_IN_DEC (0) +#define DBG_GETVAL_IN_HEX (1) +//#define DBG_GETVAL_IN_CHARS (2) + +#if (USED_UART_DEBUG_PORT == 0) +#define DEBUG_UART_PORT (UART_0) +#elif (USED_UART_DEBUG_PORT == 1) +#define DEBUG_UART_PORT (UART_1) +#elif (USED_UART_DEBUG_PORT == 2) +#define DEBUG_UART_PORT (UART_2) +#elif (USED_UART_DEBUG_PORT == 3) +#define DEBUG_UART_PORT (UART_3) +#elif (USED_UART_DEBUG_PORT == 4) +#define DEBUG_UART_PORT (UART_4) +#else + #error "Invalid UART port selection!" +#endif + +#define _DBG(x) _db_msg(DEBUG_UART_PORT, x) +#define _DBG_(x) _db_msg_(DEBUG_UART_PORT, x) + +#define _DBC(x) _db_char(DEBUG_UART_PORT, x) + +#define _DBD(x) _db_dec(DEBUG_UART_PORT, x) +#define _DBD16(x) _db_dec_16(DEBUG_UART_PORT, x) +#define _DBD32(x) _db_dec_32(DEBUG_UART_PORT, x) + +#define _DBH(x) _db_hex(DEBUG_UART_PORT, x) +#define _DBH16(x) _db_hex_16(DEBUG_UART_PORT, x) +#define _DBH32(x) _db_hex_32(DEBUG_UART_PORT, x) + +#define _DBH_(x) _db_hex_(DEBUG_UART_PORT, x) +#define _DBH16_(x) _db_hex_16_(DEBUG_UART_PORT, x) +#define _DBH32_(x) _db_hex_32_(DEBUG_UART_PORT, x) + +#define _DG _db_get_char(DEBUG_UART_PORT) +#define _DG_NONBLOCK(c) _db_get_char_nonblocking(DEBUG_UART_PORT,c) +#define _DGV(option, numCh, val) _db_get_val(DEBUG_UART_PORT, option, numCh, val) + +//void _printf (const char *format, ...); + +extern void (*_db_msg)(UART_ID_Type UartID, const void *s); +extern void (*_db_msg_)(UART_ID_Type UartID, const void *s); +extern void (*_db_char)(UART_ID_Type UartID, uint8_t ch); +extern void (*_db_dec)(UART_ID_Type UartID, uint8_t decn); +extern void (*_db_dec_16)(UART_ID_Type UartID, uint16_t decn); +extern void (*_db_dec_32)(UART_ID_Type UartID, uint32_t decn); +extern void (*_db_hex)(UART_ID_Type UartID, uint8_t hexn); +extern void (*_db_hex_16)(UART_ID_Type UartID, uint16_t hexn); +extern void (*_db_hex_32)(UART_ID_Type UartID, uint32_t hexn); +extern void (*_db_hex_)(UART_ID_Type UartID, uint8_t hexn); +extern void (*_db_hex_16_)(UART_ID_Type UartID, uint16_t hexn); +extern void (*_db_hex_32_)(UART_ID_Type UartID, uint32_t hexn); + +extern uint8_t (*_db_get_char)(UART_ID_Type UartID); +extern Bool (*_db_get_char_nonblocking)(UART_ID_Type UartID, uint8_t* c); +extern uint8_t (*_db_get_val)(UART_ID_Type UartID, uint8_t option, uint8_t numCh, uint32_t * val); + +uint8_t UARTGetValue (UART_ID_Type UartID, uint8_t option, + uint8_t numCh, uint32_t* val); +void UARTPutChar (UART_ID_Type UartID, uint8_t ch); +void UARTPuts(UART_ID_Type UartID, const void *str); +void UARTPuts_(UART_ID_Type UartID, const void *str); +void UARTPutDec(UART_ID_Type UartID, uint8_t decnum); +void UARTPutDec16(UART_ID_Type UartID, uint16_t decnum); +void UARTPutDec32(UART_ID_Type UartID, uint32_t decnum); +void UARTPutHex (UART_ID_Type UartID, uint8_t hexnum); +void UARTPutHex16 (UART_ID_Type UartID, uint16_t hexnum); +void UARTPutHex32 (UART_ID_Type UartID, uint32_t hexnum); +uint8_t UARTGetChar (UART_ID_Type UartID); +Bool UARTGetCharInNonBlock(UART_ID_Type UartID, uint8_t* c); +void debug_frmwrk_init(void); + +#endif /* __DEBUG_FRMWRK_H_ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc177x_8x_libcfg_default.h b/bsp/lpc408x/Libraries/Drivers/include/lpc177x_8x_libcfg_default.h new file mode 100644 index 0000000000000000000000000000000000000000..abea52a71cb0fb68f430fe6d0d01a114e7c7065e --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc177x_8x_libcfg_default.h @@ -0,0 +1,156 @@ +/********************************************************************** +* $Id$ lpc17xx_libcfg.h 2010-05-21 +*** +* @file lpc17xx_libcfg.h +* @brief Library configuration file +* @version 2.0 +* @date 21. May. 2010 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2010, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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 _LPC177x_8x_LIBCFG_H_ +#define _LPC177x_8x_LIBCFG_H_ + +#include "lpc_types.h" + + +/************************** DEBUG MODE DEFINITIONS *********************************/ +/* Un-comment the line below to compile the library in DEBUG mode, this will expanse + the "CHECK_PARAM" macro in the FW library code */ + +#define DEBUG + + +/******************* PERIPHERAL FW LIBRARY CONFIGURATION DEFINITIONS ***********************/ + +/* Comment the line below to disable the specific peripheral inclusion */ + +/* DEBUG_FRAMWORK -------------------- */ +#define _DBGFWK + +/* Clock & Power -------------------- */ +#define _CLKPWR + +/* CRC -------------------- */ +#define _CRC + +/* GPIO ------------------------------- */ +#define _GPIO + +/* NVIC ------------------------------- */ +#define _NVIC + +/* PINSEL ------------------------------- */ +#define _PINSEL + +/* EXTI ------------------------------- */ +#define _EXTI + +/* EMC ------------------------------- */ +#define _EMC + +/* UART ------------------------------- */ +#define _UART + +/* SPI ------------------------------- */ +#define _SPI + +/* SYSTICK --------------------------- */ +#define _SYSTICK + +/* SSP ------------------------------- */ +#define _SSP + + +/* I2C ------------------------------- */ +#define _I2C + +/* TIMER ------------------------------- */ +#define _TIM + +/* WDT ------------------------------- */ +#define _WDT + + +/* GPDMA ------------------------------- */ +#define _GPDMA + + +/* DAC ------------------------------- */ +#define _DAC + +/* ADC ------------------------------- */ +#define _ADC + +/* EEPROM ------------------------------- */ +#define _EEPROM + +/* PWM ------------------------------- */ +#define _PWM + +/* RTC ------------------------------- */ +#define _RTC + +/* I2S ------------------------------- */ +#define _I2S + +/* USB device ------------------------------- */ +#define _USBDEV +#ifdef _USBDEV +#define _USB_DEV_AUDIO +#define _USB_DEV_MASS_STORAGE +#define _USB_DEV_HID +#define _USB_DEV_VIRTUAL_COM +#endif /*_USBDEV*/ + +/* USB Host ------------------------------- */ +#define _USBHost + +/* QEI ------------------------------- */ +#define _QEI + +/* MCPWM ------------------------------- */ +#define _MCPWM + +/* CAN--------------------------------*/ +#define _CAN + +/* EMAC ------------------------------ */ +#define _EMAC + +/* LCD ------------------------------ */ +#define _LCD + +/* MCI ------------------------------ */ +#define _MCI + +/* IAP------------------------------ */ +#define _IAP + +/* BOD------------------------------ */ +#define _BOD +/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/ + + +#endif /* _LPC177x_8x_LIBCFG_H_ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_adc.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..0d0c1df9cfb6493347b70228114420929cd65658 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_adc.h @@ -0,0 +1,303 @@ +/********************************************************************** +* $Id$ lpc_adc.h 2011-06-02 +*//** +* @file lpc_adc.h +* @brief Contains all macro definitions and function prototypes +* support for ADC firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup ADC ADC (Analog-to-Digital Converter) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_ADC_H_ +#define __LPC_ADC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private macros ------------------------------------------------------------- */ +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ + +/* -------------------------- BIT DEFINITIONS ----------------------------------- */ +/*********************************************************************//** + * Macro defines for ADC control register + **********************************************************************/ + +/** Selects which of the AD0.0:7 pins (channels) is (are) to be sampled and converted */ +#define ADC_CR_CH_SEL(n) ((1UL << n)) + +/** The APB clock (PCLK) is divided by (this value plus one) +* to produce the clock for the A/D */ +#define ADC_CR_CLKDIV(n) ((n<<8)) + +/** Repeated conversions A/D enable bit */ +#define ADC_CR_BURST ((1UL<<16)) + +/** ADC convert in power down mode; if 0, it's in power down mode; if 1, it's in normal +* operation mode */ +#define ADC_CR_PDN ((1UL<<21)) + +/** Start mask bits */ +#define ADC_CR_START_MASK ((7UL<<24)) + +/** Select Start Mode controll the AD Converter in case the Burst bit is 0 (zero) */ +#define ADC_CR_START_MODE_SEL(SEL) ((SEL<<24)) + +/** Start conversion now */ +#define ADC_CR_START_NOW ((1UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on P2.10/EINT0 */ +#define ADC_CR_START_EINT0 ((2UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on P1.27/CAP0.1 */ +#define ADC_CR_START_CAP01 ((3UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on MAT0.1 */ +#define ADC_CR_START_MAT01 ((4UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on MAT0.3 */ +#define ADC_CR_START_MAT03 ((5UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on MAT1.0 */ +#define ADC_CR_START_MAT10 ((6UL<<24)) + +/** Start conversion when the edge selected by bit 27 occurs on MAT1.1 */ +#define ADC_CR_START_MAT11 ((7UL<<24)) + +/** Start conversion on a falling edge on the selected CAP/MAT signal */ +#define ADC_CR_EDGE ((1UL<<27)) + +/*********************************************************************//** + * Macro defines for ADC Global Data register + **********************************************************************/ + +/** When DONE is 1, this field contains result value of ADC conversion +* (in 12-bit value) */ +#define ADC_GDR_RESULT(n) (((n>>4)&0xFFF)) + +/** These bits contain the channel from which the LS bits were converted */ +#define ADC_GDR_CH(n) (((n>>24)&0x7)) + +/** This bits is used to mask for Channel */ +#define ADC_GDR_CH_MASK ((7UL<<24)) + +/** This bit is 1 in burst mode if the results of one or + * more conversions was (were) lost */ +#define ADC_GDR_OVERRUN_FLAG ((1UL<<30)) + +/** This bit is set to 1 when an A/D conversion completes */ +#define ADC_GDR_DONE_FLAG ((1UL<<31)) + +/*********************************************************************//** + * Macro defines for ADC Interrupt register + **********************************************************************/ + +/** These bits allow control over which A/D channels generate + * interrupts for conversion completion */ +#define ADC_INTEN_CH(n) ((1UL<>4)&0xFFF)) + +/** These bits mirror the OVERRRUN status flags that appear in the + * result register for each A/D channel */ +#define ADC_DR_OVERRUN_FLAG ((1UL<<30)) + +/** This bit is set to 1 when an A/D conversion completes. It is cleared + * when this register is read */ +#define ADC_DR_DONE_FLAG ((1UL<<31)) + +/*********************************************************************//** + * Macro defines for ADC Status register +**********************************************************************/ + +/** These bits mirror the DONE status flags that appear in the result + * register for each A/D channel */ +#define ADC_STAT_CH_DONE_FLAG(n) ((n&0xFF)) + +/** These bits mirror the OVERRRUN status flags that appear in the + * result register for each A/D channel */ +#define ADC_STAT_CH_OVERRUN_FLAG(n) (((n>>8)&0xFF)) + +/** This bit is the A/D interrupt flag */ +#define ADC_STAT_INT_FLAG ((1UL<<16)) + +/*********************************************************************//** + * Macro defines for ADC Trim register +**********************************************************************/ + +/** Offset trim bits for ADC operation */ +#define ADC_ADCOFFS(n) (((n&0xF)<<4)) + +/** Written to boot code*/ +#define ADC_TRIM(n) (((n&0xF)<<8)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup ADC_Public_Types ADC Public Types + * @{ + */ + +/*********************************************************************//** + * @brief ADC enumeration + **********************************************************************/ + +/** @brief Channel Selection */ +typedef enum +{ + ADC_CHANNEL_0 = 0, /*!< Channel 0 */ + ADC_CHANNEL_1, /*!< Channel 1 */ + ADC_CHANNEL_2, /*!< Channel 2 */ + ADC_CHANNEL_3, /*!< Channel 3 */ + ADC_CHANNEL_4, /*!< Channel 4 */ + ADC_CHANNEL_5, /*!< Channel 5 */ + ADC_CHANNEL_6, /*!< Channel 6 */ + ADC_CHANNEL_7 /*!< Channel 7 */ +}ADC_CHANNEL_SELECTION; + +/** @brief Type of start option */ +typedef enum +{ + ADC_START_CONTINUOUS = 0, /*!< Continuous mode */ + + ADC_START_NOW, /*!< Start conversion now */ + + ADC_START_ON_EINT0, /*!< Start conversion when the edge selected + * by bit 27 occurs on P2.10/EINT0 */ + ADC_START_ON_CAP01, /*!< Start conversion when the edge selected + * by bit 27 occurs on P1.27/CAP0.1 */ + ADC_START_ON_MAT01, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT0.1 */ + ADC_START_ON_MAT03, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT0.3 */ + ADC_START_ON_MAT10, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT1.0 */ + ADC_START_ON_MAT11 /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT1.1 */ +} ADC_START_OPT; + + +/** @brief Type of edge when start conversion on the selected CAP/MAT signal */ +typedef enum +{ + ADC_START_ON_RISING = 0, /*!< Start conversion on a rising edge + *on the selected CAP/MAT signal */ + ADC_START_ON_FALLING /*!< Start conversion on a falling edge + *on the selected CAP/MAT signal */ +} ADC_START_ON_EDGE_OPT; + +/** @brief* ADC type interrupt enum */ +typedef enum +{ + ADC_ADINTEN0 = 0, /*!< Interrupt channel 0 */ + ADC_ADINTEN1, /*!< Interrupt channel 1 */ + ADC_ADINTEN2, /*!< Interrupt channel 2 */ + ADC_ADINTEN3, /*!< Interrupt channel 3 */ + ADC_ADINTEN4, /*!< Interrupt channel 4 */ + ADC_ADINTEN5, /*!< Interrupt channel 5 */ + ADC_ADINTEN6, /*!< Interrupt channel 6 */ + ADC_ADINTEN7, /*!< Interrupt channel 7 */ + ADC_ADGINTEN /*!< Individual channel/global flag done generate an interrupt */ +}ADC_TYPE_INT_OPT; + +/** @brief ADC Data status */ +typedef enum +{ + ADC_DATA_BURST = 0, /*Burst bit*/ + ADC_DATA_DONE /*Done bit*/ +}ADC_DATA_STATUS; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup ADC_Public_Functions ADC Public Functions + * @{ + */ + +/* Init/DeInit ADC peripheral ----------------*/ +void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate); +void ADC_DeInit(LPC_ADC_TypeDef *ADCx); + +/* Enable/Disable ADC functions --------------*/ +void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState); +void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState); +void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode); +void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState); + +/* Configure ADC functions -------------------*/ +void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption); +void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState); + +/* Get ADC information functions -------------------*/ +uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel); +FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType); +uint32_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx); +FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC_ADC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_bod.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_bod.h new file mode 100644 index 0000000000000000000000000000000000000000..d5213d7aff79465c1d4ec4e703da961284dc6730 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_bod.h @@ -0,0 +1,98 @@ +/********************************************************************** +* $Id$ lpc_bod.h 2011-12-09 +*//** +* @file lpc_bod.h +* @brief Contain definitions & functions related to BOD. +* @version 1.0 +* @date 09 December. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup BOD BOD (Brown-Out Detector) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */#ifndef __LPC_BOD_H +#define __LPC_BOD_H +#include "lpc_types.h" +/** @defgroup BOD_Private_Macros BOD Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/********************************************************************** +** Power Mode Control register definitions +**********************************************************************/ +#define BOD_PCON_BODRPM (0x01 << 2) +#define BOD_PCON_BOGD (0x01 << 3) +#define BOD_PCON_BORD (0x01 << 4) + +/********************************************************************** +** Reset Source Identification Register definitions +**********************************************************************/ +#define BOD_RSID_POR (0x01 << 0) +#define BOD_RSID_BODR (0x01 << 3) + +/** + * @} + */ + + /** @defgroup BOD_Public_Types BOD Public Types + * @{ + */ + +/** + * @brief The field to configurate BOD + */ + +typedef struct +{ + uint8_t Enabled; /**< Enable BOD Circuit */ + uint8_t PowerReduced; /**< if ENABLE, BOD will be turned off in Power-down mode or Deep Sleep mode */ + /**< So, BOD can't be used to wake-up from these mode. */ + uint8_t ResetOnVoltageDown; /**< if ENABLE, reset the device when the VDD(REG)(3V3) voltage < the BOD reset trip level */ +}BOD_Config_Type; + +/** + * @} + */ + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup BOD_Public_Functions BOD Public Functions + * @{ + */ +void BOD_Init( BOD_Config_Type* pConfig ); +int32_t BOD_ResetSourceStatus(void); +void BOD_ResetSourceClr(void); +/** + * @} + */ +#endif /* end __LPC_BOD_H */ +/** + * @} + */ + +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_can.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_can.h new file mode 100644 index 0000000000000000000000000000000000000000..2eceebeacdd1e013961eab6cd7d2cf980e6d79a2 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_can.h @@ -0,0 +1,1014 @@ +/********************************************************************** +* $Id$ lpc_can.h 2011-06-02 +*//** +* @file lpc_can.h +* @brief Contains all macro definitions and function prototypes +* support for CAN firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup CAN CAN (Controller Area Network) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_CAN_H_ +#define __LPC_CAN_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" + +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup CAN_Public_Macros CAN Public Macros + * @{ + */ + +/** Controller ID for CAN1 */ +#define CAN1_CTRL ((uint8_t)(0)) + +/** Controller ID for CAN2 */ +#define CAN2_CTRL ((uint8_t)(1)) + +/** Message(s) Acceptance is enabled */ +#define MSG_ENABLE ((uint8_t)(0)) + +/** Message(s) Acceptance is disabled */ +#define MSG_DISABLE ((uint8_t)(1)) + + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup CAN_Private_Macros CAN Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for CAN Mode Register + **********************************************************************/ +/** CAN Reset mode */ +#define CAN_MOD_RM ((uint32_t)(1<<0)) + +/** CAN Listen Only Mode */ +#define CAN_MOD_LOM ((uint32_t)(1<<1)) + +/** CAN Self Test mode */ +#define CAN_MOD_STM ((uint32_t)(1<<2)) + +/** CAN Transmit Priority mode */ +#define CAN_MOD_TPM ((uint32_t)(1<<3)) + +/** CAN Sleep mode */ +#define CAN_MOD_SM ((uint32_t)(1<<4)) + +/** CAN Receive Polarity mode */ +#define CAN_MOD_RPM ((uint32_t)(1<<5)) + +/** CAN Test mode */ +#define CAN_MOD_TM ((uint32_t)(1<<7)) + +/*********************************************************************//** + * Macro defines for CAN Command Register + **********************************************************************/ +/** CAN Transmission Request */ +#define CAN_CMR_TR ((uint32_t)(1)) + +/** CAN Abort Transmission */ +#define CAN_CMR_AT ((uint32_t)(1<<1)) + +/** CAN Release Receive Buffer */ +#define CAN_CMR_RRB ((uint32_t)(1<<2)) + +/** CAN Clear Data Overrun */ +#define CAN_CMR_CDO ((uint32_t)(1<<3)) + +/** CAN Self Reception Request */ +#define CAN_CMR_SRR ((uint32_t)(1<<4)) + +/** CAN Select Tx Buffer 1 */ +#define CAN_CMR_STB1 ((uint32_t)(1<<5)) + +/** CAN Select Tx Buffer 2 */ +#define CAN_CMR_STB2 ((uint32_t)(1<<6)) + +/** CAN Select Tx Buffer 3 */ +#define CAN_CMR_STB3 ((uint32_t)(1<<7)) + +/*********************************************************************//** + * Macro defines for CAN Global Status Register + **********************************************************************/ +/** CAN Receive Buffer Status */ +#define CAN_GSR_RBS ((uint32_t)(1)) + +/** CAN Data Overrun Status */ +#define CAN_GSR_DOS ((uint32_t)(1<<1)) + +/** CAN Transmit Buffer Status */ +#define CAN_GSR_TBS ((uint32_t)(1<<2)) + +/** CAN Transmit Complete Status */ +#define CAN_GSR_TCS ((uint32_t)(1<<3)) + +/** CAN Receive Status */ +#define CAN_GSR_RS ((uint32_t)(1<<4)) + +/** CAN Transmit Status */ +#define CAN_GSR_TS ((uint32_t)(1<<5)) + +/** CAN Error Status */ +#define CAN_GSR_ES ((uint32_t)(1<<6)) + +/** CAN Bus Status */ +#define CAN_GSR_BS ((uint32_t)(1<<7)) + +/** CAN Current value of the Rx Error Counter */ +#define CAN_GSR_RXERR(n) ((uint32_t)((n&0xFF)<<16)) + +/** CAN Current value of the Tx Error Counter */ +#define CAN_GSR_TXERR(n) ((uint32_t)(n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Interrupt and Capture Register + **********************************************************************/ +/** CAN Receive Interrupt */ +#define CAN_ICR_RI ((uint32_t)(1)) + +/** CAN Transmit Interrupt 1 */ +#define CAN_ICR_TI1 ((uint32_t)(1<<1)) + +/** CAN Error Warning Interrupt */ +#define CAN_ICR_EI ((uint32_t)(1<<2)) + +/** CAN Data Overrun Interrupt */ +#define CAN_ICR_DOI ((uint32_t)(1<<3)) + +/** CAN Wake-Up Interrupt */ +#define CAN_ICR_WUI ((uint32_t)(1<<4)) + +/** CAN Error Passive Interrupt */ +#define CAN_ICR_EPI ((uint32_t)(1<<5)) + +/** CAN Arbitration Lost Interrupt */ +#define CAN_ICR_ALI ((uint32_t)(1<<6)) + +/** CAN Bus Error Interrupt */ +#define CAN_ICR_BEI ((uint32_t)(1<<7)) + +/** CAN ID Ready Interrupt */ +#define CAN_ICR_IDI ((uint32_t)(1<<8)) + +/** CAN Transmit Interrupt 2 */ +#define CAN_ICR_TI2 ((uint32_t)(1<<9)) + +/** CAN Transmit Interrupt 3 */ +#define CAN_ICR_TI3 ((uint32_t)(1<<10)) + +/** CAN Error Code Capture */ +#define CAN_ICR_ERRBIT(n) ((uint32_t)((n&0x1F)<<16)) + +/** CAN Error Direction */ +#define CAN_ICR_ERRDIR ((uint32_t)(1<<21)) + +/** CAN Error Capture */ +#define CAN_ICR_ERRC(n) ((uint32_t)((n&0x3)<<22)) + +/** CAN Arbitration Lost Capture */ +#define CAN_ICR_ALCBIT(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Interrupt Enable Register + **********************************************************************/ +/** CAN Receive Interrupt Enable */ +#define CAN_IER_RIE ((uint32_t)(1)) + +/** CAN Transmit Interrupt Enable for buffer 1 */ +#define CAN_IER_TIE1 ((uint32_t)(1<<1)) + +/** CAN Error Warning Interrupt Enable */ +#define CAN_IER_EIE ((uint32_t)(1<<2)) + +/** CAN Data Overrun Interrupt Enable */ +#define CAN_IER_DOIE ((uint32_t)(1<<3)) + +/** CAN Wake-Up Interrupt Enable */ +#define CAN_IER_WUIE ((uint32_t)(1<<4)) + +/** CAN Error Passive Interrupt Enable */ +#define CAN_IER_EPIE ((uint32_t)(1<<5)) + +/** CAN Arbitration Lost Interrupt Enable */ +#define CAN_IER_ALIE ((uint32_t)(1<<6)) + +/** CAN Bus Error Interrupt Enable */ +#define CAN_IER_BEIE ((uint32_t)(1<<7)) + +/** CAN ID Ready Interrupt Enable */ +#define CAN_IER_IDIE ((uint32_t)(1<<8)) + +/** CAN Transmit Enable Interrupt for Buffer 2 */ +#define CAN_IER_TIE2 ((uint32_t)(1<<9)) + +/** CAN Transmit Enable Interrupt for Buffer 3 */ +#define CAN_IER_TIE3 ((uint32_t)(1<<10)) + +/*********************************************************************//** + * Macro defines for CAN Bus Timing Register + **********************************************************************/ +/** CAN Baudrate Prescaler */ +#define CAN_BTR_BRP(n) ((uint32_t)(n&0x3FF)) + +/** CAN Synchronization Jump Width */ +#define CAN_BTR_SJM(n) ((uint32_t)((n&0x3)<<14)) + +/** CAN Time Segment 1 */ +#define CAN_BTR_TESG1(n) ((uint32_t)(n&0xF)<<16)) + +/** CAN Time Segment 2 */ +#define CAN_BTR_TESG2(n) ((uint32_t)(n&0xF)<<20)) + +/** CAN Sampling */ +#define CAN_BTR_SAM(n) ((uint32_t)(1<<23)) + +/*********************************************************************//** + * Macro defines for CAN Error Warning Limit Register + **********************************************************************/ +/** CAN Error Warning Limit */ +#define CAN_EWL_EWL(n) ((uint32_t)(n&0xFF)) + +/*********************************************************************//** + * Macro defines for CAN Status Register + **********************************************************************/ +/** CAN Receive Buffer Status */ +#define CAN_SR_RBS ((uint32_t)(1)) + +/** CAN Data Overrun Status */ +#define CAN_SR_DOS ((uint32_t)(1<<1)) + +/** CAN Transmit Buffer Status 1 */ +#define CAN_SR_TBS1 ((uint32_t)(1<<2)) + +/** CAN Transmission Complete Status of Buffer 1 */ +#define CAN_SR_TCS1 ((uint32_t)(1<<3)) + +/** CAN Receive Status */ +#define CAN_SR_RS ((uint32_t)(1<<4)) + +/** CAN Transmit Status 1 */ +#define CAN_SR_TS1 ((uint32_t)(1<<5)) + +/** CAN Error Status */ +#define CAN_SR_ES ((uint32_t)(1<<6)) + +/** CAN Bus Status */ +#define CAN_SR_BS ((uint32_t)(1<<7)) + +/** CAN Transmit Buffer Status 2 */ +#define CAN_SR_TBS2 ((uint32_t)(1<<10)) + +/** CAN Transmission Complete Status of Buffer 2 */ +#define CAN_SR_TCS2 ((uint32_t)(1<<11)) + +/** CAN Transmit Status 2 */ +#define CAN_SR_TS2 ((uint32_t)(1<<13)) + +/** CAN Transmit Buffer Status 2 */ +#define CAN_SR_TBS3 ((uint32_t)(1<<18)) + +/** CAN Transmission Complete Status of Buffer 2 */ +#define CAN_SR_TCS3 ((uint32_t)(1<<19)) + +/** CAN Transmit Status 2 */ +#define CAN_SR_TS3 ((uint32_t)(1<<21)) + +/*********************************************************************//** + * Macro defines for CAN Receive Frame Status Register + **********************************************************************/ +/** CAN ID Index */ +#define CAN_RFS_ID_INDEX(n) ((uint32_t)(n&0x3FF)) + +/** CAN Bypass */ +#define CAN_RFS_BP ((uint32_t)(1<<10)) + +/** CAN Data Length Code */ +#define CAN_RFS_DLC(n) ((uint32_t)((n&0xF)<<16) + +/** CAN Remote Transmission Request */ +#define CAN_RFS_RTR ((uint32_t)(1<<30)) + +/** CAN control 11 bit or 29 bit Identifier */ +#define CAN_RFS_FF ((uint32_t)(1<<31)) + +/*********************************************************************//** + * Macro defines for CAN Receive Identifier Register + **********************************************************************/ +/** CAN 11 bit Identifier */ +#define CAN_RID_ID_11(n) ((uint32_t)(n&0x7FF)) + +/** CAN 29 bit Identifier */ +#define CAN_RID_ID_29(n) ((uint32_t)(n&0x1FFFFFFF)) + +/*********************************************************************//** + * Macro defines for CAN Receive Data A Register + **********************************************************************/ +/** CAN Receive Data 1 */ +#define CAN_RDA_DATA1(n) ((uint32_t)(n&0xFF)) + +/** CAN Receive Data 2 */ +#define CAN_RDA_DATA2(n) ((uint32_t)((n&0xFF)<<8)) + +/** CAN Receive Data 3 */ +#define CAN_RDA_DATA3(n) ((uint32_t)((n&0xFF)<<16)) + +/** CAN Receive Data 4 */ +#define CAN_RDA_DATA4(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Receive Data B Register + **********************************************************************/ +/** CAN Receive Data 5 */ +#define CAN_RDB_DATA5(n) ((uint32_t)(n&0xFF)) + +/** CAN Receive Data 6 */ +#define CAN_RDB_DATA6(n) ((uint32_t)((n&0xFF)<<8)) + +/** CAN Receive Data 7 */ +#define CAN_RDB_DATA7(n) ((uint32_t)((n&0xFF)<<16)) + +/** CAN Receive Data 8 */ +#define CAN_RDB_DATA8(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Frame Information Register + **********************************************************************/ +/** CAN Priority */ +#define CAN_TFI_PRIO(n) ((uint32_t)(n&0xFF)) + +/** CAN Data Length Code */ +#define CAN_TFI_DLC(n) ((uint32_t)((n&0xF)<<16)) + +/** CAN Remote Frame Transmission */ +#define CAN_TFI_RTR ((uint32_t)(1<<30)) + +/** CAN control 11-bit or 29-bit Identifier */ +#define CAN_TFI_FF ((uint32_t)(1<<31)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Identifier Register + **********************************************************************/ +/** CAN 11-bit Identifier */ +#define CAN_TID_ID11(n) ((uint32_t)(n&0x7FF)) + +/** CAN 11-bit Identifier */ +#define CAN_TID_ID29(n) ((uint32_t)(n&0x1FFFFFFF)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Data A Register + **********************************************************************/ +/** CAN Transmit Data 1 */ +#define CAN_TDA_DATA1(n) ((uint32_t)(n&0xFF)) + +/** CAN Transmit Data 2 */ +#define CAN_TDA_DATA2(n) ((uint32_t)((n&0xFF)<<8)) + +/** CAN Transmit Data 3 */ +#define CAN_TDA_DATA3(n) ((uint32_t)((n&0xFF)<<16)) + +/** CAN Transmit Data 4 */ +#define CAN_TDA_DATA4(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Data B Register + **********************************************************************/ +/** CAN Transmit Data 5 */ +#define CAN_TDA_DATA5(n) ((uint32_t)(n&0xFF)) + +/** CAN Transmit Data 6 */ +#define CAN_TDA_DATA6(n) ((uint32_t)((n&0xFF)<<8)) + +/** CAN Transmit Data 7 */ +#define CAN_TDA_DATA7(n) ((uint32_t)((n&0xFF)<<16)) + +/** CAN Transmit Data 8 */ +#define CAN_TDA_DATA8(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Sleep Clear Register + **********************************************************************/ +/** CAN1 Sleep mode */ +#define CAN1SLEEPCLR ((uint32_t)(1<<1)) + +/** CAN2 Sleep Mode */ +#define CAN2SLEEPCLR ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for CAN Wake up Flags Register + **********************************************************************/ +/** CAN1 Sleep mode */ +#define CAN_WAKEFLAGES_CAN1WAKE ((uint32_t)(1<<1)) + +/** CAN2 Sleep Mode */ +#define CAN_WAKEFLAGES_CAN2WAKE ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for Central transmit Status Register + **********************************************************************/ +/** CAN Transmit 1 */ +#define CAN_TSR_TS1 ((uint32_t)(1)) + +/** CAN Transmit 2 */ +#define CAN_TSR_TS2 ((uint32_t)(1<<1)) + +/** CAN Transmit Buffer Status 1 */ +#define CAN_TSR_TBS1 ((uint32_t)(1<<8)) + +/** CAN Transmit Buffer Status 2 */ +#define CAN_TSR_TBS2 ((uint32_t)(1<<9)) + +/** CAN Transmission Complete Status 1 */ +#define CAN_TSR_TCS1 ((uint32_t)(1<<16)) + +/** CAN Transmission Complete Status 2 */ +#define CAN_TSR_TCS2 ((uint32_t)(1<<17)) + +/*********************************************************************//** + * Macro defines for Central Receive Status Register + **********************************************************************/ +/** CAN Receive Status 1 */ +#define CAN_RSR_RS1 ((uint32_t)(1)) + +/** CAN Receive Status 1 */ +#define CAN_RSR_RS2 ((uint32_t)(1<<1)) + +/** CAN Receive Buffer Status 1*/ +#define CAN_RSR_RB1 ((uint32_t)(1<<8)) + +/** CAN Receive Buffer Status 2*/ +#define CAN_RSR_RB2 ((uint32_t)(1<<9)) + +/** CAN Data Overrun Status 1 */ +#define CAN_RSR_DOS1 ((uint32_t)(1<<16)) + +/** CAN Data Overrun Status 1 */ +#define CAN_RSR_DOS2 ((uint32_t)(1<<17)) + +/*********************************************************************//** + * Macro defines for Central Miscellaneous Status Register + **********************************************************************/ +/** Same CAN Error Status in CAN1GSR */ +#define CAN_MSR_E1 ((uint32_t)(1)) + +/** Same CAN Error Status in CAN2GSR */ +#define CAN_MSR_E2 ((uint32_t)(1<<1)) + +/** Same CAN Bus Status in CAN1GSR */ +#define CAN_MSR_BS1 ((uint32_t)(1<<8)) + +/** Same CAN Bus Status in CAN2GSR */ +#define CAN_MSR_BS2 ((uint32_t)(1<<9)) + +/*********************************************************************//** + * Macro defines for Acceptance Filter Mode Register + **********************************************************************/ +/** CAN Acceptance Filter Off mode */ +#define CAN_AFMR_AccOff ((uint32_t)(1)) + +/** CAN Acceptance File Bypass mode */ +#define CAN_AFMR_AccBP ((uint32_t)(1<<1)) + +/** FullCAN Mode Enhancements */ +#define CAN_AFMR_eFCAN ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for Standard Frame Individual Start Address Register + **********************************************************************/ +/** The start address of the table of individual Standard Identifier */ +#define CAN_STT_sa(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for Standard Frame Group Start Address Register + **********************************************************************/ +/** The start address of the table of grouped Standard Identifier */ +#define CAN_SFF_GRP_sa(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for Extended Frame Start Address Register + **********************************************************************/ +/** The start address of the table of individual Extended Identifier */ +#define CAN_EFF_sa(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for Extended Frame Group Start Address Register + **********************************************************************/ +/** The start address of the table of grouped Extended Identifier */ +#define CAN_Eff_GRP_sa(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for End Of AF Table Register + **********************************************************************/ +/** The End of Table of AF LookUp Table */ +#define CAN_EndofTable(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for LUT Error Address Register + **********************************************************************/ +/** CAN Look-Up Table Error Address */ +#define CAN_LUTerrAd(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for LUT Error Register + **********************************************************************/ +/** CAN Look-Up Table Error */ +#define CAN_LUTerr ((uint32_t)(1)) + +/*********************************************************************//** + * Macro defines for Global FullCANInterrupt Enable Register + **********************************************************************/ +/** Global FullCANInterrupt Enable */ +#define CAN_FCANIE ((uint32_t)(1)) + +/*********************************************************************//** + * Macro defines for FullCAN Interrupt and Capture Register 0 + **********************************************************************/ +/** FullCAN Interrupt and Capture (0-31)*/ +#define CAN_FCANIC0_IntPnd(n) ((uint32_t)(1<=0)&&(data <= 0xFFFFFFFF)) + +/** Macro to check frequency value */ +#define PRAM_I2S_FREQ(freq) ((freq>=16000)&&(freq <= 96000)) + +/** Macro to check Frame Identifier */ +#define PARAM_ID_11(n) ((n>>11)==0) /*-- 11 bit --*/ +#define PARAM_ID_29(n) ((n>>29)==0) /*-- 29 bit --*/ + +/** Macro to check DLC value */ +#define PARAM_DLC(n) ((n>>4)==0) /*-- 4 bit --*/ + +/** Macro to check ID format type */ +#define PARAM_ID_FORMAT(n) ((n==STD_ID_FORMAT)||(n==EXT_ID_FORMAT)) + +/** Macro to check Group identifier */ +#define PARAM_GRP_ID(x, y) ((x<=y)) + +/** Macro to check Frame type */ +#define PARAM_FRAME_TYPE(n) ((n==DATA_FRAME)||(n==REMOTE_FRAME)) + +/** Macro to check Control/Central Status type parameter */ +#define PARAM_CTRL_STS_TYPE(n) ((n==CANCTRL_GLOBAL_STS)||(n==CANCTRL_INT_CAP) \ + ||(n==CANCTRL_ERR_WRN)||(n==CANCTRL_STS)) + +/** Macro to check CR status type */ +#define PARAM_CR_STS_TYPE(n) ((n==CANCR_TX_STS)||(n==CANCR_RX_STS) \ + ||(n==CANCR_MS)) + +/** Macro to check AF Mode type parameter */ +#define PARAM_AFMODE_TYPE(n) ((n==CAN_NORMAL)||(n==CAN_ACC_OFF) \ + ||(n==CAN_ACC_BP)||(n==CAN_EFCAN)) + +/** Macro to check Operation Mode */ +#define PARAM_MODE_TYPE(n) ((n==CAN_OPERATING_MODE)||(n==CAN_RESET_MODE) \ + ||(n==CAN_LISTENONLY_MODE)||(n==CAN_SELFTEST_MODE) \ + ||(n==CAN_TXPRIORITY_MODE)||(n==CAN_SLEEP_MODE) \ + ||(n==CAN_RXPOLARITY_MODE)||(n==CAN_TEST_MODE)) + +/** Macro define for struct AF_Section parameter */ +#define PARAM_CTRL(n) ((n==CAN1_CTRL)|(n==CAN2_CTRL)) + +/** Macro define for struct AF_Section parameter */ +#define PARAM_MSG_DISABLE(n) ((n==MSG_ENABLE)|(n==MSG_DISABLE)) + +/**Macro to check Interrupt Type parameter */ +#define PARAM_INT_EN_TYPE(n) ((n==CANINT_RIE)||(n==CANINT_TIE1) \ + ||(n==CANINT_EIE)||(n==CANINT_DOIE) \ + ||(n==CANINT_WUIE)||(n==CANINT_EPIE) \ + ||(n==CANINT_ALIE)||(n==CANINT_BEIE) \ + ||(n==CANINT_IDIE)||(n==CANINT_TIE2) \ + ||(n==CANINT_TIE3)||(n==CANINT_FCE)) + +/** Macro to check AFLUT Entry type */ +#define PARAM_AFLUT_ENTRY_TYPE(n) ((n==FULLCAN_ENTRY)||(n==EXPLICIT_STANDARD_ENTRY)\ + ||(n==GROUP_STANDARD_ENTRY)||(n==EXPLICIT_EXTEND_ENTRY) \ + ||(n==GROUP_EXTEND_ENTRY)) + +/** Macro to check position */ +#define PARAM_POSITION(n) ((n>=0)&&(n<512)) + +/** + * @} + */ + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup CAN_Public_Types CAN Public Types + * @{ + */ + + +/*********************************************************************** + * CAN device configuration commands (IOCTL commands and arguments) + **********************************************************************/ +/** CAN peripheral ID 0 */ +#define CAN_1 0 + +/** CAN peripheral ID 1 */ +#define CAN_2 1 + +/** + * @brief CAN peripheral ID no + */ +typedef enum +{ + CAN_ID_1 = CAN_1, + CAN_ID_2 = CAN_2 +} en_CAN_unitId; + +/** + * @brief CAN ID format definition + */ +typedef enum +{ + STD_ID_FORMAT = 0, /**< Use standard ID format (11 bit ID) */ + EXT_ID_FORMAT = 1 /**< Use extended ID format (29 bit ID) */ +} CAN_ID_FORMAT_Type; + +/** + * @brief AFLUT Entry type definition + */ +typedef enum +{ + FULLCAN_ENTRY = 0, + EXPLICIT_STANDARD_ENTRY, + GROUP_STANDARD_ENTRY, + EXPLICIT_EXTEND_ENTRY, + GROUP_EXTEND_ENTRY, +} AFLUT_ENTRY_Type; + +/** + * @brief Symbolic names for type of CAN message + */ +typedef enum +{ + DATA_FRAME = 0, /**< Data frame */ + REMOTE_FRAME = 1 /**< Remote frame */ +} CAN_FRAME_Type; + +/** + * @brief CAN Control status definition + */ +typedef enum +{ + CANCTRL_GLOBAL_STS = 0, /**< CAN Global Status */ + CANCTRL_INT_CAP, /**< CAN Interrupt and Capture */ + CANCTRL_ERR_WRN, /**< CAN Error Warning Limit */ + CANCTRL_STS /**< CAN Control Status */ +} CAN_CTRL_STS_Type; + +/** + * @brief Central CAN status type definition + */ +typedef enum +{ + CANCR_TX_STS = 0, /**< Central CAN Tx Status */ + CANCR_RX_STS, /**< Central CAN Rx Status */ + CANCR_MS /**< Central CAN Miscellaneous Status */ +} CAN_CR_STS_Type; + +/** + * @brief FullCAN Interrupt Capture type definition + */ +typedef enum +{ + FULLCAN_IC0, /**< FullCAN Interrupt and Capture 0 */ + FULLCAN_IC1 /**< FullCAN Interrupt and Capture 1 */ +}FullCAN_IC_Type; + +/** + * @brief CAN interrupt enable type definition + */ +typedef enum +{ + CANINT_RIE = 0, /**< CAN Receiver Interrupt Enable */ + CANINT_TIE1, /**< CAN Transmit Interrupt Enable */ + CANINT_EIE, /**< CAN Error Warning Interrupt Enable */ + CANINT_DOIE, /**< CAN Data Overrun Interrupt Enable */ + CANINT_WUIE, /**< CAN Wake-Up Interrupt Enable */ + CANINT_EPIE, /**< CAN Error Passive Interrupt Enable */ + CANINT_ALIE, /**< CAN Arbitration Lost Interrupt Enable */ + CANINT_BEIE, /**< CAN Bus Error Inter rupt Enable */ + CANINT_IDIE, /**< CAN ID Ready Interrupt Enable */ + CANINT_TIE2, /**< CAN Transmit Interrupt Enable for Buffer2 */ + CANINT_TIE3, /**< CAN Transmit Interrupt Enable for Buffer3 */ + CANINT_FCE /**< FullCAN Interrupt Enable */ +} CAN_INT_EN_Type; + +/** + * @brief Acceptance Filter Mode type definition + */ +typedef enum +{ + CAN_NORMAL = 0, /**< Normal Mode */ + CAN_ACC_OFF, /**< Acceptance Filter Off Mode */ + CAN_ACC_BP, /**< Acceptance Fileter Bypass Mode */ + CAN_EFCAN /**< FullCAN Mode Enhancement */ +} CAN_AFMODE_Type; + +/** + * @brief CAN Mode Type definition + */ +typedef enum +{ + CAN_OPERATING_MODE = 0, /**< Operating Mode */ + CAN_RESET_MODE, /**< Reset Mode */ + CAN_LISTENONLY_MODE, /**< Listen Only Mode */ + CAN_SELFTEST_MODE, /**< Seft Test Mode */ + CAN_TXPRIORITY_MODE, /**< Transmit Priority Mode */ + CAN_SLEEP_MODE, /**< Sleep Mode */ + CAN_RXPOLARITY_MODE, /**< Receive Polarity Mode */ + CAN_TEST_MODE /**< Test Mode */ +} CAN_MODE_Type; + +/** + * @brief Error values that functions can return + */ +typedef enum +{ + CAN_OK = 1, /**< No error */ + CAN_OBJECTS_FULL_ERROR, /**< No more rx or tx objects available */ + CAN_FULL_OBJ_NOT_RCV, /**< Full CAN object not received */ + CAN_NO_RECEIVE_DATA, /**< No have receive data available */ + CAN_AF_ENTRY_ERROR, /**< Entry load in AFLUT is unvalid */ + CAN_CONFLICT_ID_ERROR, /**< Conflict ID occur */ + CAN_ENTRY_NOT_EXIT_ERROR /**< Entry remove outo AFLUT is not exit */ +} CAN_ERROR; + +/** + * @brief Pin Configuration structure + */ +typedef struct +{ + uint8_t RD; /**< Serial Inputs, from CAN transceivers, should be: + ** For CAN1: + - CAN_RD1_P0_0: RD pin is on P0.0 + - CAN_RD1_P0_21 : RD pin is on P0.21 + ** For CAN2: + - CAN_RD2_P0_4: RD pin is on P0.4 + - CAN_RD2_P2_7: RD pin is on P2.7 + */ + uint8_t TD; /**< Serial Outputs, To CAN transceivers, should be: + ** For CAN1: + - CAN_TD1_P0_1: TD pin is on P0.1 + - CAN_TD1_P0_22: TD pin is on P0.22 + ** For CAN2: + - CAN_TD2_P0_5: TD pin is on P0.5 + - CAN_TD2_P2_8: TD pin is on P2.8 + */ +} CAN_PinCFG_Type; + +/** + * @brief CAN message object structure + */ +typedef struct +{ + uint32_t id; /**< 29 bit identifier, it depend on "format" value + - if format = STD_ID_FORMAT, id should be 11 bit identifier + - if format = EXT_ID_FORMAT, id should be 29 bit identifier + */ + uint8_t dataA[4]; /**< Data field A */ + uint8_t dataB[4]; /**< Data field B */ + uint8_t len; /**< Length of data field in bytes, should be: + - 0000b-0111b: 0-7 bytes + - 1xxxb: 8 bytes + */ + uint8_t format; /**< Identifier Format, should be: + - STD_ID_FORMAT: Standard ID - 11 bit format + - EXT_ID_FORMAT: Extended ID - 29 bit format + */ + uint8_t type; /**< Remote Frame transmission, should be: + - DATA_FRAME: the number of data bytes called out by the DLC + field are send from the CANxTDA and CANxTDB registers + - REMOTE_FRAME: Remote Frame is sent + */ +} CAN_MSG_Type; + +/** + * @brief FullCAN Entry structure + */ +typedef struct +{ + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable; /**< Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t id_11; /**< Standard ID, should be 11-bit value */ +} FullCAN_Entry; + +/** + * @brief Standard ID Frame Format Entry structure + */ +typedef struct +{ + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable; /**< Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t id_11; /**< Standard ID, should be 11-bit value */ +} SFF_Entry; + +/** + * @brief Group of Standard ID Frame Format Entry structure + */ +typedef struct +{ + uint8_t controller1; /**< First CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable1; /**< First Disable bit, should be: + - MSG_ENABLE: disable bit = 0) + - MSG_DISABLE: disable bit = 1 + */ + uint16_t lowerID; /**< ID lower bound, should be 11-bit value */ + uint8_t controller2; /**< Second CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable2; /**< Second Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t upperID; /**< ID upper bound, should be 11-bit value and + equal or greater than lowerID + */ +} SFF_GPR_Entry; + +/** + * @brief Extended ID Frame Format Entry structure + */ +typedef struct +{ + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint32_t ID_29; /**< Extend ID, shoud be 29-bit value */ +} EFF_Entry; + + +/** + * @brief Group of Extended ID Frame Format Entry structure + */ +typedef struct +{ + uint8_t controller1; /**< First CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t controller2; /**< Second Disable bit, should be: + - MSG_ENABLE: disable bit = 0(default) + - MSG_DISABLE: disable bit = 1 + */ + uint32_t lowerEID; /**< Extended ID lower bound, should be 29-bit value */ + uint32_t upperEID; /**< Extended ID upper bound, should be 29-bit value */ +} EFF_GPR_Entry; + + +/** + * @brief Acceptance Filter Section Table structure + */ +typedef struct +{ + FullCAN_Entry* FullCAN_Sec; /**< The pointer point to FullCAN_Entry */ + uint8_t FC_NumEntry; /**< FullCAN Entry Number */ + SFF_Entry* SFF_Sec; /**< The pointer point to SFF_Entry */ + uint8_t SFF_NumEntry; /**< Standard ID Entry Number */ + SFF_GPR_Entry* SFF_GPR_Sec; /**< The pointer point to SFF_GPR_Entry */ + uint8_t SFF_GPR_NumEntry; /**< Group Standard ID Entry Number */ + EFF_Entry* EFF_Sec; /**< The pointer point to EFF_Entry */ + uint8_t EFF_NumEntry; /**< Extended ID Entry Number */ + EFF_GPR_Entry* EFF_GPR_Sec; /**< The pointer point to EFF_GPR_Entry */ + uint8_t EFF_GPR_NumEntry; /**< Group Extended ID Entry Number */ +} AF_SectionDef; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup CAN_Public_Functions CAN Public Functions + * @{ + */ + +/* Init/DeInit CAN peripheral -----------*/ +void CAN_Init(uint8_t canId, uint32_t baudrate); +void CAN_DeInit(uint8_t canId); + +/* CAN messages functions ---------------*/ +Status CAN_SendMsg(uint8_t canId, CAN_MSG_Type *CAN_Msg); +Status CAN_ReceiveMsg(uint8_t canId, CAN_MSG_Type *CAN_Msg); +CAN_ERROR FCAN_ReadObj(CAN_MSG_Type *CAN_Msg); + +/* CAN configure functions ---------------*/ +void CAN_ModeConfig(uint8_t canId, CAN_MODE_Type mode, + FunctionalState NewState); +void CAN_SetAFMode(CAN_AFMODE_Type AFmode); +void CAN_SetCommand(uint8_t canId, uint32_t CMRType); + +/* AFLUT functions ---------------------- */ +CAN_ERROR CAN_SetupAFLUT(AF_SectionDef* AFSection); +CAN_ERROR CAN_LoadFullCANEntry(uint8_t canId, uint16_t ID); +CAN_ERROR CAN_LoadExplicitEntry(uint8_t canId, uint32_t ID, + CAN_ID_FORMAT_Type format); +CAN_ERROR CAN_LoadGroupEntry(uint8_t canId, uint32_t lowerID, + uint32_t upperID, CAN_ID_FORMAT_Type format); +CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position); + +/* CAN interrupt functions -----------------*/ +void CAN_IRQCmd(uint8_t canId, CAN_INT_EN_Type arg, FunctionalState NewState); +uint32_t CAN_IntGetStatus(uint8_t canId); + +/* CAN get status functions ----------------*/ +IntStatus CAN_FullCANIntGetStatus (void); +uint32_t CAN_FullCANPendGetStatus (FullCAN_IC_Type type); +uint32_t CAN_GetCTRLStatus(uint8_t canId, CAN_CTRL_STS_Type arg); +uint32_t CAN_GetCRStatus(CAN_CR_STS_Type arg); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC_CAN_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_clkpwr.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_clkpwr.h new file mode 100644 index 0000000000000000000000000000000000000000..5895d9dd5906112f3326a0f2e8b7fe1e1c4af6ce --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_clkpwr.h @@ -0,0 +1,248 @@ +/********************************************************************** +* $Id$ lpc_clkpwr.h 2011-06-02 +*//** +* @file lpc_clkpwr.h +* @brief Contains all macro definitions and function prototypes +* support for Clock and Power Control firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup CLKPWR CLKPWR (Clock Power) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_CLKPWR_H_ +#define __LPC_CLKPWR_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" +#include "system_LPC407x_8x_177x_8x.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup CLKPWR_Public_Macros CLKPWR Public Macros + * @{ + */ + +/******************************************************************** +* Clock Source Selection Definitions +**********************************************************************/ +#define CLKPWR_CLKSRCSEL_IRCOSC ((uint32_t)(0)) +#define CLKPWR_CLKSRCSEL_MAINOSC ((uint32_t)(1)) + +/******************************************************************** +* Clock type/domain Definitions (calculated from input and pre-configuration +* parameter(s) +**********************************************************************/ +#define CLKPWR_CLKTYPE_CPU ((uint32_t)(0)) +#define CLKPWR_CLKTYPE_PER ((uint32_t)(1)) +#define CLKPWR_CLKTYPE_EMC ((uint32_t)(2)) +#define CLKPWR_CLKTYPE_USB ((uint32_t)(3)) + +/******************************************************************** +* Power Control for Peripherals Definitions +**********************************************************************/ +/** LCD controller power/clock control bit */ +#define CLKPWR_PCONP_PCLCD ((uint32_t)(1<<0)) + +/** Timer/Counter 0 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM0 ((uint32_t)(1<<1)) + +/* Timer/Counter 1 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM1 ((uint32_t)(1<<2)) + +/** UART0 power/clock control bit */ +#define CLKPWR_PCONP_PCUART0 ((uint32_t)(1<<3)) + +/** UART1 power/clock control bit */ +#define CLKPWR_PCONP_PCUART1 ((uint32_t)(1<<4)) + +/** PWM0 power/clock control bit */ +#define CLKPWR_PCONP_PCPWM0 ((uint32_t)(1<<5)) + +/** PWM1 power/clock control bit */ +#define CLKPWR_PCONP_PCPWM1 ((uint32_t)(1<<6)) + +/** The I2C0 interface power/clock control bit */ +#define CLKPWR_PCONP_PCI2C0 ((uint32_t)(1<<7)) + +/** UART4 power/clock control bit */ +#define CLKPWR_PCONP_PCUART4 ((uint32_t)(1<<8)) + +/** The RTC power/clock control bit */ +#define CLKPWR_PCONP_PCRTC ((uint32_t)(1<<9)) + +/** The SSP1 interface power/clock control bit */ +#define CLKPWR_PCONP_PCSSP1 ((uint32_t)(1<<10)) + +/** External Memory controller power/clock control bit */ +#define CLKPWR_PCONP_PCEMC ((uint32_t)(1<<11)) + +/** A/D converter 0 (ADC0) power/clock control bit */ +#define CLKPWR_PCONP_PCADC ((uint32_t)(1<<12)) + +/** CAN Controller 1 power/clock control bit */ +#define CLKPWR_PCONP_PCAN1 ((uint32_t)(1<<13)) + +/** CAN Controller 2 power/clock control bit */ +#define CLKPWR_PCONP_PCAN2 ((uint32_t)(1<<14)) + +/** GPIO power/clock control bit */ +#define CLKPWR_PCONP_PCGPIO ((uint32_t)(1<<15)) + +/** Motor Control PWM */ +#define CLKPWR_PCONP_PCMCPWM ((uint32_t)(1<<17)) + +/** Quadrature Encoder Interface power/clock control bit */ +#define CLKPWR_PCONP_PCQEI ((uint32_t)(1<<18)) + +/** The I2C1 interface power/clock control bit */ +#define CLKPWR_PCONP_PCI2C1 ((uint32_t)(1<<19)) + +/** The SSP2 interface power/clock control bit */ +#define CLKPWR_PCONP_PCSSP2 ((uint32_t)(1<<20)) + +/** The SSP0 interface power/clock control bit */ +#define CLKPWR_PCONP_PCSSP0 ((uint32_t)(1<<21)) + +/** Timer 2 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM2 ((uint32_t)(1<<22)) + +/** Timer 3 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM3 ((uint32_t)(1<<23)) + +/** UART 2 power/clock control bit */ +#define CLKPWR_PCONP_PCUART2 ((uint32_t)(1<<24)) + +/** UART 3 power/clock control bit */ +#define CLKPWR_PCONP_PCUART3 ((uint32_t)(1<<25)) + +/** I2C interface 2 power/clock control bit */ +#define CLKPWR_PCONP_PCI2C2 ((uint32_t)(1<<26)) + +/** I2S interface power/clock control bit*/ +#define CLKPWR_PCONP_PCI2S ((uint32_t)(1<<27)) + +/** SD card interface power/clock control bit */ +#define CLKPWR_PCONP_PCSDC ((uint32_t)(1<<28)) + +/** GP DMA function power/clock control bit*/ +#define CLKPWR_PCONP_PCGPDMA ((uint32_t)(1<<29)) + +/** Ethernet block power/clock control bit*/ +#define CLKPWR_PCONP_PCENET ((uint32_t)(1<<30)) + +/** USB interface power/clock control bit*/ +#define CLKPWR_PCONP_PCUSB ((uint32_t)(1<<31)) + +/******************************************************************** +* Power Control for Peripherals Definitions +**********************************************************************/ +#define CLKPWR_RSTCON0_LCD ((uint32_t)(0)) +#define CLKPWR_RSTCON0_TIM0 ((uint32_t)(1)) +#define CLKPWR_RSTCON0_TIM1 ((uint32_t)(2)) +#define CLKPWR_RSTCON0_UART0 ((uint32_t)(3)) +#define CLKPWR_RSTCON0_UART1 ((uint32_t)(4)) +#define CLKPWR_RSTCON0_PWM0 ((uint32_t)(5)) +#define CLKPWR_RSTCON0_PWM1 ((uint32_t)(6)) +#define CLKPWR_RSTCON0_I2C0 ((uint32_t)(7)) +#define CLKPWR_RSTCON0_UART4 ((uint32_t)(8)) +#define CLKPWR_RSTCON0_RTC ((uint32_t)(9)) +#define CLKPWR_RSTCON0_SSP1 ((uint32_t)(10)) +#define CLKPWR_RSTCON0_EMC ((uint32_t)(11)) +#define CLKPWR_RSTCON0_ADC ((uint32_t)(12)) +#define CLKPWR_RSTCON0_CAN1 ((uint32_t)(13)) +#define CLKPWR_RSTCON0_CAN2 ((uint32_t)(14)) +#define CLKPWR_RSTCON0_GPIO ((uint32_t)(15)) +#define CLKPWR_RSTCON0_MCPWM ((uint32_t)(17)) +#define CLKPWR_RSTCON0_QEI ((uint32_t)(18)) +#define CLKPWR_RSTCON0_I2C1 ((uint32_t)(19)) +#define CLKPWR_RSTCON0_SSP2 ((uint32_t)(20)) +#define CLKPWR_RSTCON0_SSP0 ((uint32_t)(21)) +#define CLKPWR_RSTCON0_TIM2 ((uint32_t)(22)) +#define CLKPWR_RSTCON0_TIM3 ((uint32_t)(23)) +#define CLKPWR_RSTCON0_UART2 ((uint32_t)(24)) +#define CLKPWR_RSTCON0_UART3 ((uint32_t)(25)) +#define CLKPWR_RSTCON0_I2C2 ((uint32_t)(26)) +#define CLKPWR_RSTCON0_I2S ((uint32_t)(27)) +#define CLKPWR_RSTCON0_SDC ((uint32_t)(28)) +#define CLKPWR_RSTCON0_GPDMA ((uint32_t)(29)) +#define CLKPWR_RSTCON0_ENET ((uint32_t)(30)) +#define CLKPWR_RSTCON0_USB ((uint32_t)(31)) + +#define CLKPWR_RSTCON1_IOCON ((uint32_t)(32)) +#define CLKPWR_RSTCON1_DAC ((uint32_t)(33)) +#define CLKPWR_RSTCON1_CANACC ((uint32_t)(34)) +/** + * @} + */ + +/* External clock variable from system_LPC407x_8x_177x_8x.h */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency (Pclk) */ +extern uint32_t EMCClock; /*!< EMC Clock Frequency */ + +/* External clock variable from lpc_clkpwr.h */ +extern uint32_t USBClock; /*!< USB Frequency */ + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup CLKPWR_Public_Functions CLKPWR Public Functions + * @{ + */ + +void CLKPWR_SetCLKDiv(uint8_t ClkType, uint8_t DivVal); +uint32_t CLKPWR_GetCLK(uint8_t ClkType); +void CLKPWR_ConfigPPWR(uint32_t PPType, FunctionalState NewState); +void CLKPWR_ConfigReset(uint8_t PType, FunctionalState NewState); +void CLKPWR_Sleep(void); +void CLKPWR_DeepSleep(void); +void CLKPWR_PowerDown(void); +void CLKPWR_DeepPowerDown(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_CLKPWR_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_crc.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..acbfbd57bd6cc32540493c904a8979cd63e0d046 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_crc.h @@ -0,0 +1,110 @@ +/********************************************************************** +* $Id$ lpc_crc.h 2011-06-02 +*//** +* @file lpc_crc.h +* @brief Contains all macro definitions and function prototypes +* support for CRC firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup CRC CRC (Cyclic Redundancy Check) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC__CRC_H_ +#define __LPC__CRC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private macros ------------------------------------------------------------- */ +/** @defgroup CRC_Private_Macros CRC Private Macros + * @{ + */ + +/* -------------------------- BIT DEFINITIONS ----------------------------------- */ +/*********************************************************************//** + * Macro defines for CRC mode register + **********************************************************************/ +#define CRC_BIT_RVS_WR (1<<2) +#define CRC_CMPL_WR (1<<3) +#define CRC_BIT_RVS_SUM (1<<4) +#define CRC_CMPL_SUM (1<<5) + + +/** + * @} + */ +/* Private types ------------------------------------------------------------- */ +typedef enum +{ + CRC_POLY_CRCCCITT = 0, /** CRC CCITT polynomial */ + CRC_POLY_CRC16, /** CRC-16 polynomial */ + CRC_POLY_CRC32 /** CRC-32 polynomial */ +}CRC_Type; + +typedef enum +{ + CRC_WR_8BIT = 1, /** 8-bit write: 1-cycle operation */ + CRC_WR_16BIT = 2, /** 16-bit write: 2-cycle operation */ + CRC_WR_32BIT = 4, /** 32-bit write: 4-cycle operation */ +}CRC_WR_SIZE; + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup CRC_Public_Functions CRC Public Functions + * @{ + */ +void CRC_Init(CRC_Type CRCType); +void CRC_Reset(void); +uint32_t CRC_CalcDataChecksum(uint32_t data, CRC_WR_SIZE SizeType); +uint32_t CRC_CalcBlockChecksum(void *blockdata, uint32_t blocksize, CRC_WR_SIZE SizeType); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __LPC_CRC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_dac.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..1cb376b3c334cba36dc1546fea04254713649c32 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_dac.h @@ -0,0 +1,165 @@ +/********************************************************************** +* $Id$ lpc_dac.h 2011-06-02 +*//** +* @file lpc_dac.h +* @brief Contains all macro definitions and function prototypes +* support for DAC firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup DAC DAC (Digital-to-Analog Converter) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_DAC_H_ +#define __LPC_DAC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" + +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup DAC_Private_Macros DAC Private Macros + * @{ + */ + +/** After the selected settling time after this field is written with a +new VALUE, the voltage on the AOUT pin (with respect to VSSA) +is VALUE/1024 × VREF */ +#define DAC_VALUE(n) ((uint32_t)((n&0x3FF)<<6)) + +/** If this bit = 0: The settling time of the DAC is 1 microsecond max, + * and the maximum current is 700 microAmpere + * If this bit = 1: The settling time of the DAC is 2.5 microsecond + * and the maximum current is 350 microAmpere */ +#define DAC_BIAS_EN ((uint32_t)(1<<16)) + +/** Value to reload interrupt DMA counter */ +#define DAC_CCNT_VALUE(n) ((uint32_t)(n&0xffff)) + +/** DCAR double buffering */ +#define DAC_DBLBUF_ENA ((uint32_t)(1<<1)) + +/** DCAR Time out count enable */ +#define DAC_CNT_ENA ((uint32_t)(1<<2)) + +/** DCAR DMA access */ +#define DAC_DMA_ENA ((uint32_t)(1<<3)) + +/** DCAR DACCTRL mask bit */ +#define DAC_DACCTRL_MASK ((uint32_t)(0x0F)) + +/** Macro to determine if it is valid DAC peripheral */ +#define PARAM_DACx(n) (((uint32_t *)n)==((uint32_t *)LPC_DAC)) + +/** Macro to check DAC current optional parameter */ +#define PARAM_DAC_CURRENT_OPT(OPTION) ((OPTION == DAC_MAX_CURRENT_700uA)\ + ||(OPTION == DAC_MAX_CURRENT_350uA)) +/** + * @} + */ +/* Public Types --------------------------------------------------------------- */ +/** @defgroup DAC_Public_Types DAC Public Types + * @{ + */ + +/** + * @brief Current option in DAC configuration option */ +typedef enum +{ + DAC_MAX_CURRENT_700uA = 0, /*!< The settling time of the DAC is 1 us max, + and the maximum current is 700 uA */ + DAC_MAX_CURRENT_350uA /*!< The settling time of the DAC is 2.5 us + and the maximum current is 350 uA */ +} DAC_CURRENT_OPT; + +/** + * @brief Configuration for DAC converter control register */ +typedef struct +{ + + uint8_t DBLBUF_ENA; /**< + - If 0: Disable DACR double buffering + + - If 1: when bit CNT_ENA, enable DACR double buffering feature + */ + uint8_t CNT_ENA; /*!< + - If 0: Time out counter is disable + + -1: Time out conter is enable + */ + uint8_t DMA_ENA; /*!< + - If 0: DMA access is disable + + - If 1: DMA burst request + */ + uint8_t RESERVED; + +} DAC_CONVERTER_CFG_Type; + +/** + * @} + */ + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup DAC_Public_Functions DAC Public Functions + * @{ + */ + +void DAC_Init(uint8_t DAC_Id); +void DAC_UpdateValue (uint8_t DAC_Id, uint32_t dac_value); +void DAC_SetBias (uint8_t DAC_Id,uint32_t bias); +void DAC_ConfigDAConverterControl (uint8_t DAC_Id,DAC_CONVERTER_CFG_Type *DAC_ConverterConfigStruct); +void DAC_SetDMATimeOut(uint8_t DAC_Id,uint32_t time_out); +uint8_t DAC_IsIntRequested(uint8_t DAC_Id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __LPC_DAC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_eeprom.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..56acda355eecc7d8c48e60509fea9a0f84c67211 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_eeprom.h @@ -0,0 +1,152 @@ +/********************************************************************** +* $Id$ lpc_eeprom.h 2011-06-02 +*//** +* @file lpc_eeprom.h +* @brief Contains all macro definitions and function prototypes +* support for EEPROM firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup EEPROM EEPROM (Electrically Erasable Programmable Read-Only Memory) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_EEPROM_H_ +#define __LPC_EEPROM_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private macros ------------------------------------------------------------- */ +/** @defgroup EEPROM_Private_Macros EEPROM Private Macros + * @{ + */ + +/* -------------------------- BIT DEFINITIONS --------------------------------- */ +/*********************************************************************//** + * Macro defines for EEPROM command register + **********************************************************************/ +#define EEPROM_CMD_8_BIT_READ (0) +#define EEPROM_CMD_16_BIT_READ (1) +#define EEPROM_CMD_32_BIT_READ (2) +#define EEPROM_CMD_8_BIT_WRITE (3) +#define EEPROM_CMD_16_BIT_WRITE (4) +#define EEPROM_CMD_32_BIT_WRITE (5) +#define EEPROM_CMD_ERASE_PRG_PAGE (6) + +#define EEPROM_CMD_RDPREFETCH (1<<3) + +#define EEPROM_PAGE_SIZE 64 +#define EEPROM_PAGE_NUM 63 + +/*********************************************************************//** + * Macro defines for EEPROM address register + **********************************************************************/ +#define EEPROM_PAGE_OFFSET(n) (n&0x3F) +#define EEPROM_PAGE_ADRESS(n) ((n&0x3F)<<6) + +/*********************************************************************//** + * Macro defines for EEPROM write data register + **********************************************************************/ +#define EEPROM_WDATA_8_BIT(n) (n&0x000000FF) +#define EEPROM_WDATA_16_BIT(n) (n&0x0000FFFF) +#define EEPROM_WDATA_32_BIT(n) (n&0xFFFFFFFF) + +/*********************************************************************//** + * Macro defines for EEPROM read data register + **********************************************************************/ +#define EEPROM_RDATA_8_BIT(n) (n&0x000000FF) +#define EEPROM_RDATA_16_BIT(n) (n&0x0000FFFF) +#define EEPROM_RDATA_32_BIT(n) (n&0xFFFFFFFF) + +/*********************************************************************//** + * Macro defines for EEPROM power down register + **********************************************************************/ +#define EEPROM_PWRDWN (1<<0) + +#define EEPROM_ENDOF_RW (26) +#define EEPROM_ENDOF_PROG (28) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup EEPROM_Public_Types EEPROM Public Types + * @{ + */ + +typedef enum +{ + MODE_8_BIT = 0, + MODE_16_BIT, + MODE_32_BIT +}EEPROM_Mode_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup EEPROM_Public_Functions EEPROM Public Functions + * @{ + */ + +void EEPROM_Init(void); +void EEPROM_Write(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t size); +void EEPROM_Read(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t size); +void EEPROM_Erase(uint16_t address); +void EEPROM_PowerDown(FunctionalState NewState); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __LPC_EEPROM_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_emac.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..3d18f31b45d3460bde0c5907d920338d7862cbad --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_emac.h @@ -0,0 +1,616 @@ +/********************************************************************** +* $Id$ lpc_emac.h 2011-06-02 +*//** +* @file lpc_emac.h +* @brief Contains all macro definitions and function prototypes +* support for Ethernet MAC firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup EMAC EMAC (Ethernet Media Access Controller) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_EMAC_H_ +#define __LPC_EMAC_H_ + +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @defgroup EMAC_Private_Macros EMAC Private Macros + * @{ + */ + +/* Ethernet MAC register definitions --------------------------------------------------------------------- */ +/* MAC Configuration Register 1 */ +#define EMAC_MAC1_MASK 0xcf1f /*MAC1 register mask*/ +#define EMAC_MAC1_REC_EN 0x00000001 /**< Receive Enable */ +#define EMAC_MAC1_PASS_ALL 0x00000002 /**< Pass All Receive Frames */ +#define EMAC_MAC1_RX_FLOWC 0x00000004 /**< RX Flow Control */ +#define EMAC_MAC1_TX_FLOWC 0x00000008 /**< TX Flow Control */ +#define EMAC_MAC1_LOOPB 0x00000010 /**< Loop Back Mode */ +#define EMAC_MAC1_RES_TX 0x00000100 /**< Reset TX Logic */ +#define EMAC_MAC1_RES_MCS_TX 0x00000200 /**< Reset MAC TX Control Sublayer */ +#define EMAC_MAC1_RES_RX 0x00000400 /**< Reset RX Logic */ +#define EMAC_MAC1_RES_MCS_RX 0x00000800 /**< Reset MAC RX Control Sublayer */ +#define EMAC_MAC1_SIM_RES 0x00004000 /**< Simulation Reset */ +#define EMAC_MAC1_SOFT_RES 0x00008000 /**< Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define EMAC_MAC2_MASK 0x73ff /*MAC2 register mask*/ +#define EMAC_MAC2_FULL_DUP 0x00000001 /**< Full-Duplex Mode */ +#define EMAC_MAC2_FRM_LEN_CHK 0x00000002 /**< Frame Length Checking */ +#define EMAC_MAC2_HUGE_FRM_EN 0x00000004 /**< Huge Frame Enable */ +#define EMAC_MAC2_DLY_CRC 0x00000008 /**< Delayed CRC Mode */ +#define EMAC_MAC2_CRC_EN 0x00000010 /**< Append CRC to every Frame */ +#define EMAC_MAC2_PAD_EN 0x00000020 /**< Pad all Short Frames */ +#define EMAC_MAC2_VLAN_PAD_EN 0x00000040 /**< VLAN Pad Enable */ +#define EMAC_MAC2_ADET_PAD_EN 0x00000080 /**< Auto Detect Pad Enable */ +#define EMAC_MAC2_PPREAM_ENF 0x00000100 /**< Pure Preamble Enforcement */ +#define EMAC_MAC2_LPREAM_ENF 0x00000200 /**< Long Preamble Enforcement */ +#define EMAC_MAC2_NO_BACKOFF 0x00001000 /**< No Backoff Algorithm */ +#define EMAC_MAC2_BACK_PRESSURE 0x00002000 /**< Backoff Presurre / No Backoff */ +#define EMAC_MAC2_EXCESS_DEF 0x00004000 /**< Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +/** Programmable field representing the nibble time offset of the minimum possible period + * between the end of any transmitted packet to the beginning of the next */ +#define EMAC_IPGT_BBIPG(n) (n&0x7F) + +/** Recommended value for Full Duplex of Programmable field representing the nibble time + * offset of the minimum possible period between the end of any transmitted packet to the + * beginning of the next */ +#define EMAC_IPGT_FULL_DUP (EMAC_IPGT_BBIPG(0x15)) + +/** Recommended value for Half Duplex of Programmable field representing the nibble time + * offset of the minimum possible period between the end of any transmitted packet to the + * beginning of the next */ +#define EMAC_IPGT_HALF_DUP (EMAC_IPGT_BBIPG(0x12)) + +/* Non Back-to-Back Inter-Packet-Gap Register */ +/** Programmable field representing the Non-Back-to-Back Inter-Packet-Gap */ +#define EMAC_IPGR_NBBIPG_P2(n) (n&0x7F) + +/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 1 */ +#define EMAC_IPGR_P2_DEF (EMAC_IPGR_NBBIPG_P2(0x12)) + +/** Programmable field representing the optional carrierSense window referenced in + * IEEE 802.3/4.2.3.2.1 'Carrier Deference' */ +#define EMAC_IPGR_NBBIPG_P1(n) ((n&0x7F)<<8) + +/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 2 */ +#define EMAC_IPGR_P1_DEF EMAC_IPGR_NBBIPG_P1(0x0C) + +/* Collision Window/Retry Register */ +/** Programmable field specifying the number of retransmission attempts following a collision before + * aborting the packet due to excessive collisions */ +#define EMAC_CLRT_MAX_RETX(n) (n&0x0F) + +/** Programmable field representing the slot time or collision window during which collisions occur + * in properly configured networks */ +#define EMAC_CLRT_COLL(n) ((n&0x3F)<<8) + +/** Default value for Collision Window / Retry register */ +#define EMAC_CLRT_DEF ((EMAC_CLRT_MAX_RETX(0x0F))|(EMAC_CLRT_COLL(0x37))) + +/* Maximum Frame Register */ +/** Represents a maximum receive frame of 1536 octets */ +#define EMAC_MAXF_MAXFRMLEN(n) (n&0xFFFF) +#define EMAC_MAXF_MAXFRMLEN_DEF (0x6000) + +/* PHY Support Register */ +#define EMAC_SUPP_SPEED 0x00000100 /**< Reduced MII Logic Current Speed */ +//#define EMAC_SUPP_RES_RMII 0x00000800 /**< Reset Reduced MII Logic */ + +/* Test Register */ +#define EMAC_TEST_SHCUT_PQUANTA 0x00000001 /**< Shortcut Pause Quanta */ +#define EMAC_TEST_TST_PAUSE 0x00000002 /**< Test Pause */ +#define EMAC_TEST_TST_BACKP 0x00000004 /**< Test Back Pressure */ + +/* MII Management Configuration Register */ +#define EMAC_MCFG_SCAN_INC 0x00000001 /**< Scan Increment PHY Address */ +#define EMAC_MCFG_SUPP_PREAM 0x00000002 /**< Suppress Preamble */ +#define EMAC_MCFG_CLK_SEL(n) ((n&0x0F)<<2) /**< Clock Select Field */ +#define EMAC_MCFG_RES_MII 0x00008000 /**< Reset MII Management Hardware */ +#define EMAC_MCFG_MII_MAXCLK 2500000UL /**< MII Clock max */ + +/* MII Management Command Register */ +#define EMAC_MCMD_READ 0x00000001 /**< MII Read */ +#define EMAC_MCMD_SCAN 0x00000002 /**< MII Scan continuously */ + +#define EMAC_MII_WR_TOUT 0x00050000 /**< MII Write timeout count */ +#define EMAC_MII_RD_TOUT 0x00050000 /**< MII Read timeout count */ + +/* MII Management Address Register */ +#define EMAC_MADR_REG_ADR(n) (n&0x1F) /**< MII Register Address field */ +#define EMAC_MADR_PHY_ADR(n) ((n&0x1F)<<8) /**< PHY Address Field */ + +/* MII Management Write Data Register */ +#define EMAC_MWTD_DATA(n) (n&0xFFFF) /**< Data field for MMI Management Write Data register */ + +/* MII Management Read Data Register */ +#define EMAC_MRDD_DATA(n) (n&0xFFFF) /**< Data field for MMI Management Read Data register */ + +/* MII Management Indicators Register */ +#define EMAC_MIND_BUSY 0x00000001 /**< MII is Busy */ +#define EMAC_MIND_SCAN 0x00000002 /**< MII Scanning in Progress */ +#define EMAC_MIND_NOT_VAL 0x00000004 /**< MII Read Data not valid */ +#define EMAC_MIND_MII_LINK_FAIL 0x00000008 /**< MII Link Failed */ + +/* Station Address 0 Register */ +/* Station Address 1 Register */ +/* Station Address 2 Register */ + + +/* Control register definitions --------------------------------------------------------------------------- */ +/* Command Register */ +#define EMAC_CR_RX_EN 0x00000001 /**< Enable Receive */ +#define EMAC_CR_TX_EN 0x00000002 /**< Enable Transmit */ +#define EMAC_CR_REG_RES 0x00000008 /**< Reset Host Registers */ +#define EMAC_CR_TX_RES 0x00000010 /**< Reset Transmit Datapath */ +#define EMAC_CR_RX_RES 0x00000020 /**< Reset Receive Datapath */ +#define EMAC_CR_PASS_RUNT_FRM 0x00000040 /**< Pass Runt Frames */ +#define EMAC_CR_PASS_RX_FILT 0x00000080 /**< Pass RX Filter */ +#define EMAC_CR_TX_FLOW_CTRL 0x00000100 /**< TX Flow Control */ +#define EMAC_CR_RMII 0x00000200 /**< Reduced MII Interface */ +#define EMAC_CR_FULL_DUP 0x00000400 /**< Full Duplex */ + +/* Status Register */ +#define EMAC_SR_RX_EN 0x00000001 /**< Enable Receive */ +#define EMAC_SR_TX_EN 0x00000002 /**< Enable Transmit */ + +/* Receive Descriptor Base Address Register */ +// + +/* Receive Status Base Address Register */ +// + +/* Receive Number of Descriptors Register */ +// + +/* Receive Produce Index Register */ +// + +/* Receive Consume Index Register */ +// + +/* Transmit Descriptor Base Address Register */ +// + +/* Transmit Status Base Address Register */ +// + +/* Transmit Number of Descriptors Register */ +// + +/* Transmit Produce Index Register */ +// + +/* Transmit Consume Index Register */ +// + +/* Transmit Status Vector 0 Register */ +#define EMAC_TSV0_CRC_ERR 0x00000001 /**< CRC error */ +#define EMAC_TSV0_LEN_CHKERR 0x00000002 /**< Length Check Error */ +#define EMAC_TSV0_LEN_OUTRNG 0x00000004 /**< Length Out of Range */ +#define EMAC_TSV0_DONE 0x00000008 /**< Tramsmission Completed */ +#define EMAC_TSV0_MCAST 0x00000010 /**< Multicast Destination */ +#define EMAC_TSV0_BCAST 0x00000020 /**< Broadcast Destination */ +#define EMAC_TSV0_PKT_DEFER 0x00000040 /**< Packet Deferred */ +#define EMAC_TSV0_EXC_DEFER 0x00000080 /**< Excessive Packet Deferral */ +#define EMAC_TSV0_EXC_COLL 0x00000100 /**< Excessive Collision */ +#define EMAC_TSV0_LATE_COLL 0x00000200 /**< Late Collision Occured */ +#define EMAC_TSV0_GIANT 0x00000400 /**< Giant Frame */ +#define EMAC_TSV0_UNDERRUN 0x00000800 /**< Buffer Underrun */ +#define EMAC_TSV0_BYTES 0x0FFFF000 /**< Total Bytes Transferred */ +#define EMAC_TSV0_CTRL_FRAME 0x10000000 /**< Control Frame */ +#define EMAC_TSV0_PAUSE 0x20000000 /**< Pause Frame */ +#define EMAC_TSV0_BACK_PRESS 0x40000000 /**< Backpressure Method Applied */ +#define EMAC_TSV0_VLAN 0x80000000 /**< VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define EMAC_TSV1_BYTE_CNT 0x0000FFFF /**< Transmit Byte Count */ +#define EMAC_TSV1_COLL_CNT 0x000F0000 /**< Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define EMAC_RSV_BYTE_CNT 0x0000FFFF /**< Receive Byte Count */ +#define EMAC_RSV_PKT_IGNORED 0x00010000 /**< Packet Previously Ignored */ +#define EMAC_RSV_RXDV_SEEN 0x00020000 /**< RXDV Event Previously Seen */ +#define EMAC_RSV_CARR_SEEN 0x00040000 /**< Carrier Event Previously Seen */ +#define EMAC_RSV_REC_CODEV 0x00080000 /**< Receive Code Violation */ +#define EMAC_RSV_CRC_ERR 0x00100000 /**< CRC Error */ +#define EMAC_RSV_LEN_CHKERR 0x00200000 /**< Length Check Error */ +#define EMAC_RSV_LEN_OUTRNG 0x00400000 /**< Length Out of Range */ +#define EMAC_RSV_REC_OK 0x00800000 /**< Frame Received OK */ +#define EMAC_RSV_MCAST 0x01000000 /**< Multicast Frame */ +#define EMAC_RSV_BCAST 0x02000000 /**< Broadcast Frame */ +#define EMAC_RSV_DRIB_NIBB 0x04000000 /**< Dribble Nibble */ +#define EMAC_RSV_CTRL_FRAME 0x08000000 /**< Control Frame */ +#define EMAC_RSV_PAUSE 0x10000000 /**< Pause Frame */ +#define EMAC_RSV_UNSUPP_OPC 0x20000000 /**< Unsupported Opcode */ +#define EMAC_RSV_VLAN 0x40000000 /**< VLAN Frame */ + +/* Flow Control Counter Register */ +#define EMAC_FCC_MIRR_CNT(n) (n&0xFFFF) /**< Mirror Counter */ +#define EMAC_FCC_PAUSE_TIM(n) ((n&0xFFFF)<<16) /**< Pause Timer */ + +/* Flow Control Status Register */ +#define EMAC_FCS_MIRR_CNT(n) (n&0xFFFF) /**< Mirror Counter Current */ + + +/* Receive filter register definitions -------------------------------------------------------- */ +/* Receive Filter Control Register */ +#define EMAC_RFC_UCAST_EN 0x00000001 /**< Accept Unicast Frames Enable */ +#define EMAC_RFC_BCAST_EN 0x00000002 /**< Accept Broadcast Frames Enable */ +#define EMAC_RFC_MCAST_EN 0x00000004 /**< Accept Multicast Frames Enable */ +#define EMAC_RFC_UCAST_HASH_EN 0x00000008 /**< Accept Unicast Hash Filter Frames */ +#define EMAC_RFC_MCAST_HASH_EN 0x00000010 /**< Accept Multicast Hash Filter Fram.*/ +#define EMAC_RFC_PERFECT_EN 0x00000020 /**< Accept Perfect Match Enable */ +#define EMAC_RFC_MAGP_WOL_EN 0x00001000 /**< Magic Packet Filter WoL Enable */ +#define EMAC_RFC_PFILT_WOL_EN 0x00002000 /**< Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define EMAC_WOL_UCAST 0x00000001 /**< Unicast Frame caused WoL */ +#define EMAC_WOL_BCAST 0x00000002 /**< Broadcast Frame caused WoL */ +#define EMAC_WOL_MCAST 0x00000004 /**< Multicast Frame caused WoL */ +#define EMAC_WOL_UCAST_HASH 0x00000008 /**< Unicast Hash Filter Frame WoL */ +#define EMAC_WOL_MCAST_HASH 0x00000010 /**< Multicast Hash Filter Frame WoL */ +#define EMAC_WOL_PERFECT 0x00000020 /**< Perfect Filter WoL */ +#define EMAC_WOL_RX_FILTER 0x00000080 /**< RX Filter caused WoL */ +#define EMAC_WOL_MAG_PACKET 0x00000100 /**< Magic Packet Filter caused WoL */ +#define EMAC_WOL_BITMASK 0x01BF /**< Receive Filter WoL Status/Clear bitmasl value */ + +/* Hash Filter Table LSBs Register */ +// + +/* Hash Filter Table MSBs Register */ +// + + +/* Module control register definitions ---------------------------------------------------- */ +/* Interrupt Status/Enable/Clear/Set Registers */ +#define EMAC_INT_RX_OVERRUN 0x00000001 /**< Overrun Error in RX Queue */ +#define EMAC_INT_RX_ERR 0x00000002 /**< Receive Error */ +#define EMAC_INT_RX_FIN 0x00000004 /**< RX Finished Process Descriptors */ +#define EMAC_INT_RX_DONE 0x00000008 /**< Receive Done */ +#define EMAC_INT_TX_UNDERRUN 0x00000010 /**< Transmit Underrun */ +#define EMAC_INT_TX_ERR 0x00000020 /**< Transmit Error */ +#define EMAC_INT_TX_FIN 0x00000040 /**< TX Finished Process Descriptors */ +#define EMAC_INT_TX_DONE 0x00000080 /**< Transmit Done */ +#define EMAC_INT_SOFT_INT 0x00001000 /**< Software Triggered Interrupt */ +#define EMAC_INT_WAKEUP 0x00002000 /**< Wakeup Event Interrupt */ + +/* Power Down Register */ +#define EMAC_PD_POWER_DOWN 0x80000000 /**< Power Down MAC */ + + +/* Descriptor and status formats ------------------------------------------------------ */ +/* RX and TX descriptor and status definitions. */ + +/* EMAC Memory Buffer configuration for 16K Ethernet RAM */ +#define EMAC_NUM_RX_FRAG 4 /**< Num.of RX Fragments 4*1536= 6.0kB */ +#define EMAC_NUM_TX_FRAG 3 /**< Num.of TX Fragments 3*1536= 4.6kB */ +#define EMAC_ETH_MAX_FLEN 1536 /**< Max. Ethernet Frame Size */ +#define EMAC_TX_FRAME_TOUT 0x00100000 /**< Frame Transmit timeout count */ + +/* EMAC variables located in 16K Ethernet SRAM */ +#define RX_DESC_BASE LPC_PERI_RAM_BASE +#define RX_STAT_BASE (RX_DESC_BASE + EMAC_NUM_RX_FRAG*8) +#define TX_DESC_BASE (RX_STAT_BASE + EMAC_NUM_RX_FRAG*8) +#define TX_STAT_BASE (TX_DESC_BASE + EMAC_NUM_TX_FRAG*8) +#define RX_BUF_BASE (TX_STAT_BASE + EMAC_NUM_TX_FRAG*4) +#define TX_BUF_BASE (RX_BUF_BASE + EMAC_NUM_RX_FRAG*EMAC_ETH_MAX_FLEN) + +/** + * @brief RX Descriptor structure type definition + */ +#define RX_DESC_PACKET(i) (*(uint32_t *)(RX_DESC_BASE + 8*i)) +#define RX_DESC_CTRL(i) (*(uint32_t *)(RX_DESC_BASE+4 + 8*i)) + +/** + * @brief RX Status structure type definition + */ +#define RX_STAT_INFO(i) (*(uint32_t *)(RX_STAT_BASE + 8*i)) +#define RX_STAT_HASHCRC(i) (*(uint32_t *)(RX_STAT_BASE+4 + 8*i)) + +/** + * @brief TX Descriptor structure type definition + */ +#define TX_DESC_PACKET(i) (*(uint32_t *)(TX_DESC_BASE + 8*i)) +#define TX_DESC_CTRL(i) (*(uint32_t *)(TX_DESC_BASE+4 + 8*i)) + +/** + * @brief TX Status structure type definition + */ +#define TX_STAT_INFO(i) (*(uint32_t *)(TX_STAT_BASE + 4*i)) + + +/** + * @brief TX Data Buffer structure definition + */ +#define RX_BUF(i) (RX_BUF_BASE + EMAC_ETH_MAX_FLEN*i) +#define TX_BUF(i) (TX_BUF_BASE + EMAC_ETH_MAX_FLEN*i) + +/* RX Descriptor Control Word */ +#define EMAC_RCTRL_SIZE(n) (n&0x7FF) /**< Buffer size field */ +#define EMAC_RCTRL_INT 0x80000000 /**< Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define EMAC_RHASH_SA 0x000001FF /**< Hash CRC for Source Address */ +#define EMAC_RHASH_DA 0x001FF000 /**< Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define EMAC_RINFO_SIZE 0x000007FF /**< Data size in bytes */ +#define EMAC_RINFO_CTRL_FRAME 0x00040000 /**< Control Frame */ +#define EMAC_RINFO_VLAN 0x00080000 /**< VLAN Frame */ +#define EMAC_RINFO_FAIL_FILT 0x00100000 /**< RX Filter Failed */ +#define EMAC_RINFO_MCAST 0x00200000 /**< Multicast Frame */ +#define EMAC_RINFO_BCAST 0x00400000 /**< Broadcast Frame */ +#define EMAC_RINFO_CRC_ERR 0x00800000 /**< CRC Error in Frame */ +#define EMAC_RINFO_SYM_ERR 0x01000000 /**< Symbol Error from PHY */ +#define EMAC_RINFO_LEN_ERR 0x02000000 /**< Length Error */ +#define EMAC_RINFO_RANGE_ERR 0x04000000 /**< Range Error (exceeded max. size) */ +#define EMAC_RINFO_ALIGN_ERR 0x08000000 /**< Alignment Error */ +#define EMAC_RINFO_OVERRUN 0x10000000 /**< Receive overrun */ +#define EMAC_RINFO_NO_DESCR 0x20000000 /**< No new Descriptor available */ +#define EMAC_RINFO_LAST_FLAG 0x40000000 /**< Last Fragment in Frame */ +#define EMAC_RINFO_ERR 0x80000000 /**< Error Occured (OR of all errors) */ + +/** RX Status Information word mask */ +#define EMAC_RINFO_ERR_MASK (EMAC_RINFO_FAIL_FILT | EMAC_RINFO_CRC_ERR | EMAC_RINFO_SYM_ERR | \ + EMAC_RINFO_LEN_ERR | EMAC_RINFO_ALIGN_ERR | EMAC_RINFO_OVERRUN) + +/* TX Descriptor Control Word */ +#define EMAC_TCTRL_SIZE 0x000007FF /**< Size of data buffer in bytes */ +#define EMAC_TCTRL_OVERRIDE 0x04000000 /**< Override Default MAC Registers */ +#define EMAC_TCTRL_HUGE 0x08000000 /**< Enable Huge Frame */ +#define EMAC_TCTRL_PAD 0x10000000 /**< Pad short Frames to 64 bytes */ +#define EMAC_TCTRL_CRC 0x20000000 /**< Append a hardware CRC to Frame */ +#define EMAC_TCTRL_LAST 0x40000000 /**< Last Descriptor for TX Frame */ +#define EMAC_TCTRL_INT 0x80000000 /**< Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define EMAC_TINFO_COL_CNT 0x01E00000 /**< Collision Count */ +#define EMAC_TINFO_DEFER 0x02000000 /**< Packet Deferred (not an error) */ +#define EMAC_TINFO_EXCESS_DEF 0x04000000 /**< Excessive Deferral */ +#define EMAC_TINFO_EXCESS_COL 0x08000000 /**< Excessive Collision */ +#define EMAC_TINFO_LATE_COL 0x10000000 /**< Late Collision Occured */ +#define EMAC_TINFO_UNDERRUN 0x20000000 /**< Transmit Underrun */ +#define EMAC_TINFO_NO_DESCR 0x40000000 /**< No new Descriptor available */ +#define EMAC_TINFO_ERR 0x80000000 /**< Error Occured (OR of all errors) */ + + +/* DP83848C PHY definition ------------------------------------------------------------ */ + +/** PHY device reset time out definition */ +#define EMAC_PHY_RESP_TOUT 0x100000UL + +/* ENET Device Revision ID */ +#define EMAC_OLD_EMAC_MODULE_ID 0x39022000 /**< Rev. ID for first rev '-' */ + + +/* PHY Basic Mode Control Register (BMCR) bitmap definitions */ +#define EMAC_PHY_BMCR_LOOPBACK (1<<14) /**< Loop back */ +//#define EMAC_PHY_BMCR_AN (1<<12) /**< Auto Negotiation */ + +#define EMAC_PHY_BMCR_ISOLATE (1<<10) /**< Isolate */ +#define EMAC_PHY_BMCR_RE_AN (1<<9) /**< Restart auto negotiation */ + +#define EMAC_PHY_BMSR_NOPREAM (1<<6) /**< MF Preamable Supress */ +#define EMAC_PHY_BMSR_AUTO_DONE (1<<5) /**< Auto negotiation complete */ + + +#define EMAC_PHY_FULLD_100M (EMAC_PHY_BMCR_SPEED_SEL | EMAC_PHY_BMCR_DUPLEX) // Full Duplex 100Mbit +#define EMAC_PHY_HALFD_100M (EMAC_PHY_BMCR_SPEED_SEL | (~ EMAC_PHY_BMCR_DUPLEX)) // Half Duplex 100Mbit +#define EMAC_PHY_FULLD_10M ((~ EMAC_PHY_BMCR_SPEED_SEL) | EMAC_PHY_BMCR_DUPLEX) // Full Duplex 10Mbit +#define EMAC_PHY_HALFD_10M ((~ EMAC_PHY_BMCR_SPEED_SEL) | (~EMAC_PHY_BMCR_DUPLEX)) // Half Duplex 10MBit +#define EMAC_PHY_AUTO_NEG (EMAC_PHY_BMCR_SPEED_SEL | EMAC_PHY_BMCR_AN) // Select Auto Negotiation + + + +/* EMAC PHY status type definitions */ +#define EMAC_PHY_STAT_LINK (0) /**< Link Status */ +#define EMAC_PHY_STAT_SPEED (1) /**< Speed Status */ +#define EMAC_PHY_STAT_DUP (2) /**< Duplex Status */ + +/* EMAC PHY device Speed definitions */ +#define EMAC_MODE_AUTO (0) /**< Auto-negotiation mode */ +#define EMAC_MODE_10M_FULL (1) /**< 10Mbps FullDuplex mode */ +#define EMAC_MODE_10M_HALF (2) /**< 10Mbps HalfDuplex mode */ +#define EMAC_MODE_100M_FULL (3) /**< 100Mbps FullDuplex mode */ +#define EMAC_MODE_100M_HALF (4) /**< 100Mbps HalfDuplex mode */ + +/* EMAC User Buffers*/ +#define EMAC_MAX_FRAME_SIZE (0x600) /* 1536 */ +#define EMAC_MAX_FRAME_NUM (2) + +/* EMAC Error Codes */ +#define EMAC_ALIGN_ERR ( 1 << 0) +#define EMAC_RANGE_ERR ( 1 << 1) +#define EMAC_LENGTH_ERR ( 1 << 2) +#define EMAC_SYMBOL_ERR ( 1 << 3) +#define EMAC_CRC_ERR ( 1 << 4) +#define EMAC_RX_NO_DESC_ERR ( 1 << 5) +#define EMAC_OVERRUN_ERR ( 1 << 6) +#define EMAC_LATE_COLLISION_ERR ( 1 << 7) +#define EMAC_EXCESSIVE_COLLISION_ERR ( 1 << 8) +#define EMAC_EXCESSIVE_DEFER_ERR ( 1 << 9) +#define EMAC_UNDERRUN_ERR ( 1 << 10) +#define EMAC_TX_NO_DESC_ERR ( 1 << 11) +#define EMAC_FILTER_FAILED_ERR ( 1 << 12) + + +/** + * @} + */ + + +/**************************** GLOBAL/PUBLIC TYPES ***************************/ + +/** @defgroup EMAC_Public_Types EMAC Public Types + * @{ + */ + +/** + * @brief TX Data Buffer structure definition + */ +typedef struct { + uint32_t ulDataLen; /**< Data length */ + uint32_t *pbDataBuf; /**< A word-align data pointer to data buffer */ +} EMAC_PACKETBUF_Type; + +/** + * @brief PHY Configuration structure definition + */ +typedef struct { + uint32_t Mode; /**< Supported EMAC PHY device speed, should be one of the following: + - EMAC_MODE_AUTO + - EMAC_MODE_10M_FULL + - EMAC_MODE_10M_HALF + - EMAC_MODE_100M_FULL + - EMAC_MODE_100M_HALF + */ +} EMAC_PHY_CFG_Type; + + +/** EMAC Call back function type definition */ +typedef int32_t (PHY_INIT_FUNC)(EMAC_PHY_CFG_Type* pPhyCfg); +typedef int32_t (PHY_RESET_FUNC)(void); +typedef void (EMAC_FRAME_RECV_FUNC)(uint16_t* pData, uint32_t size); +typedef void (EMAC_TRANSMIT_FINISH_FUNC)(void); +typedef void (EMAC_ERR_RECV_FUNC)(int32_t ulErrCode); +typedef void (EMAC_WAKEUP_FUNC)(void); +typedef void (SOFT_INT_FUNC)(void); + +/** + * @brief EMAC configuration structure definition + */ +typedef struct { + EMAC_PHY_CFG_Type PhyCfg; /* PHY Configuration */ + uint8_t bPhyAddr; /* 5-bit PHY Address field */ + uint8_t *pbEMAC_Addr; /**< Pointer to EMAC Station address that contains 6-bytes + of MAC address, it must be sorted in order (bEMAC_Addr[0]..[5]) + */ + uint16_t nMaxFrameSize; /* maximum frame length */ + PHY_INIT_FUNC *pfnPHYInit; /* point to the funtion which will be called to initialize PHY */ + PHY_RESET_FUNC *pfnPHYReset; /* point to the function which will be called to reset PHY */ + EMAC_FRAME_RECV_FUNC *pfnFrameReceive; /* point to the function which will be called when a frame is received*/ + EMAC_TRANSMIT_FINISH_FUNC* pfnTransmitFinish; /*point to the function which will be called when transmit finished*/ + EMAC_ERR_RECV_FUNC *pfnErrorReceive; /* point to an array of functions which will be called error occur. */ + /* Errors: + EMAC_ALIGN_ERR + EMAC_RANGE_ERR + EMAC_LENGTH_ERR + EMAC_SYMBOL_ERR + EMAC_CRC_ERR + EMAC_RX_NO_DESC_ERR + EMAC_OVERRUN_ERR + EMAC_LATE_COLLISION_ERR + EMAC_EXCESSIVE_COLLISION_ERR + EMAC_EXCESSIVE_DEFER_ERR + EMAC_UNDERRUN_ERR + EMAC_TX_NO_DESC_ERR + */ + EMAC_WAKEUP_FUNC *pfnWakeup; /* point to the function which will be called when receiving wakeup interrupt */ + SOFT_INT_FUNC *pfnSoftInt; /* point to the function which will be called when the interrupt caused by software occurs */ +} EMAC_CFG_Type; + +/** + * @brief EMAC Buffer status definition + */ +typedef enum { + EMAC_BUFF_EMPTY, /* buffer is empty */ + EMAC_BUFF_PARTIAL_FULL, /* buffer contains some packets */ + EMAC_BUFF_FULL, /* buffer is full */ +} EMAC_BUFF_STATUS; + +/** + * @brief EMAC Buffer Index definition + */ + +typedef enum { + EMAC_TX_BUFF, /* transmit buffer */ + EMAC_RX_BUFF, /* receive buffer */ +} EMAC_BUFF_IDX; + +/** + * @} + */ + + +/** @defgroup EMAC_Public_Functions EMAC Public Functions + * @{ + */ + +/** Init/DeInit */ +int32_t EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct); +void EMAC_DeInit(void); + +/** Send/Receive data */ +void EMAC_TxEnable( void ); +void EMAC_RxEnable( void ); +void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState); +int32_t EMAC_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len); +void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct); + +/** PHY Setup */ +void EMAC_Write_PHY (uint8_t PhyReg, uint16_t Value); +uint16_t EMAC_Read_PHY (uint8_t PhyReg); +void EMAC_SetFullDuplexMode(uint8_t full_duplex); +void EMAC_SetPHYSpeed(uint8_t mode_100Mbps); + +/** Filter */ +void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState); +FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode); +void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState); +IntStatus EMAC_IntGetStatus(uint32_t ulIntType); +EMAC_BUFF_STATUS EMAC_GetBufferSts(EMAC_BUFF_IDX idx); + + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_EMAC_DRIVER_H_ */ + +/** + * @} + */ + diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_emc.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_emc.h new file mode 100644 index 0000000000000000000000000000000000000000..6bcc18d4768a6b3396c2f46ed7611ed7a486b597 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_emc.h @@ -0,0 +1,549 @@ +/********************************************************************** +* $Id$ lpc_emc.h 2011-06-02 +*//** +* @file lpc_emc.h +* @brief Contains all macro definitions and function prototypes +* support for EMC firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup EMC EMC (External Memory Controller) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_EMC_H_ +#define __LPC_EMC_H_ + +#include "lpc_types.h" +#include "LPC407x_8x_177x_8x.h" + + +/** @defgroup EMC_Private_Macros EMC Private Macros + * @{ + */ + +/*********************************************************************** + * EMC Control Register (EMCControl) + **********************************************************************/ +/* Control register mask */ +#define EMC_Control_MASK ((uint32_t )0x07) +/* Control register EMC: Enable control. */ +#define EMC_Control_E ((uint32_t )(1<<0)) +/* Control register EMC: Address mirror control. */ +#define EMC_Control_M ((uint32_t )(1<<1)) +/* Control register EMC: Low-power mode control. */ +#define EMC_Control_L ((uint32_t )(1<<2)) + +/*********************************************************************** + * EMC Status Register (EMCStatus) + **********************************************************************/ +/* Status register mask */ +#define EMC_Status_MASK ((uint32_t )0x07) +/* Status register EMC: Busy. */ +#define EMC_Status_B ((uint32_t )(1<<0)) +/* Status register EMC: Write buffer status. */ +#define EMC_Status_S ((uint32_t )(1<<1)) +/* Status register EMC: Self-refresh acknowledge.. */ +#define EMC_Status_SA ((uint32_t )(1<<2)) + +/*********************************************************************** + * EMC Configuration register (EMCConfig) + **********************************************************************/ +/* EMC Configuration register : Little Endian. */ +#define EMC_Config_Little_Endian_Mode ((uint32_t )(0<<0)) +/* EMC Configuration register : Big Endian. */ +#define EMC_Config_Big_Endian_Mode ((uint32_t )(1<<0)) +/* EMC Configuration: Endian Mask */ +#define EMC_Config_Endian_Mask (0x01<<0) + +/* EMC Configuration register: CLKOUT ratio 1:1. */ +#define EMC_Config_CCLK_1_1 ((uinr32_t)(0<<8)) +/* EMC Configuration register: CLKOUT ratio 1:1. */ +#define EMC_Config_CCLK_1_2 ((uinr32_t)(1<<8)) + +/* EMC Configuration register mask */ +#define EMC_Config_MASK ((uint32_t)(0x101)) + + +/*********************************************************************** + * Dynamic Memory Control register (EMCDynamicControl) + **********************************************************************/ +/* Dynamic Memory Control register EMC: Dynamic memory clock enable. */ +#define EMC_DYNAMIC_CTRL_MEMCLK_EN_POS (0) +#define EMC_DYNAMIC_CTRL_MEMCLK_EN_BMASK (1<>9) & 0x0F) +#define CARD_STATE_IDLE (0) +#define CARD_STATE_READY (1) +#define CARD_STATE_IDENT (2) +#define CARD_STATE_STBY (3) +#define CARD_STATE_TRAN (4) +#define CARD_STATE_DATA (5) +#define CARD_STATE_RCV (6) +#define CARD_STATE_PRG (7) +#define CARD_STATE_DIS (8) + + +/* CID in R2 reponse (Code length is 136 bits) */ +#define MCI_CID_MANUFACTURER_ID_WPOS (24) //pos in word 0 +#define MCI_CID_MANUFACTURER_ID_WBMASK (0xFF) + +#define MCI_CID_OEMAPPLICATION_ID_WPOS (8) //pos in word 0 +#define MCI_CID_OEMAPPLICATION_ID_WBMASK (0xFFFF) + +#define MCI_CID_PRODUCTNAME_ID_H_WPOS (0) //pos in word 0 +#define MCI_CID_PRODUCTNAME_ID_H_WBMASK (0xFF) + +#define MCI_CID_PRODUCTNAME_ID_L_WPOS (0) //pos in word 1 +#define MCI_CID_PRODUCTNAME_ID_L_WBMASK (0xFFFFFFFF) + +#define MCI_CID_PRODUCTREVISION_ID_WPOS (24) //pos in word 2 +#define MCI_CID_PRODUCTREVISION_ID_WBMASK (0xFF) + +#define MCI_CID_PRODUCTSERIALNUM_ID_H_WPOS (0) //pos in word 2 +#define MCI_CID_PRODUCTSERIALNUM_ID_H_WBMASK (0x00FFFFFF) +#define MCI_CID_PRODUCTSERIALNUM_ID_L_WPOS (24) //pos in word 3 +#define MCI_CID_PRODUCTSERIALNUM_ID_L_WBMASK (0xFF) +#define MCI_CID_PRODUCTSERIALNUM_ID_WBMASK (0xFFFFFFFF) + +#define MCI_CID_RESERVED_ID_WPOS (20) //pos in word 3 +#define MCI_CID_RESERVED_ID_WBMASK (0x1F) + +#define MCI_CID_MANUFACTURINGDATE_ID_WPOS (8) //in word 3 +#define MCI_CID_MANUFACTURINGDATE_ID_WBMASK (0x0FFF) + +#define MCI_CID_CHECKSUM_ID_WPOS (1) //in word 3 +#define MCI_CID_CHECKSUM_ID_WBMASK (0x7F) + +#define MCI_CID_UNUSED_ID_WPOS (0) //in word 3 +#define MCI_CID_UNUSED_ID_WBMASK (0x01) + +/* R6 (Published RCA response) */ +#define RCA_RES_CARD_STATUS_POS (0) +#define RCA_RES_CARD_STATUS_MASK (0xFFFF) + +#define RCA_RES_NEW_PUBLISHED_RCA_POS (16) +#define RCA_RES_NEW_PUBLISHED_RCA_MASK (0xFFFF) + +/* R7 (Card interface condition) */ +#define MCI_CMD8_VOLTAGESUPPLIED_POS (8) +#define MCI_CMD8_VOLTAGESUPPLIED_BMASK (0x0F) +#define MCI_CMD8_VOLATAGESUPPLIED_NOT_DEFINED (0) +#define MCI_CMD8_VOLATAGESUPPLIED_27_36 (1) /*2.7 - 3.6V*/ + +#define MCI_CMD8_CHECKPATTERN_POS (0) +#define MCI_CMD8_CHECKPATTERN_BMASK (0xFF) + + +#define MCI_SLOW_RATE (400000) /* 400KHz */ +#define MCI_NORMAL_RATE (20000000) /* 20MHz */ + +#define SD_1_BIT (0) +#define SD_4_BIT (1) + +#define DATA_TIMER_VALUE_R (MCI_NORMAL_RATE/4) // 250ms +#define DATA_TIMER_VALUE_W (MCI_NORMAL_RATE) // 1000ms + +#define DATA_RW_MAX_LEN (0xFFFF) + +#define EXPECT_NO_RESP (0) +#define EXPECT_SHORT_RESP (1) +#define EXPECT_LONG_RESP (2) + +#define MCI_OUTPUT_MODE_PUSHPULL (0) +#define MCI_OUTPUT_MODE_OPENDRAIN (1) + +#define NOT_ALLOW_CMD_TIMER (0) +#define ALLOW_CMD_TIMER (1) + +#define MCI_DISABLE_CMD_TIMER (1<<8) + +/* For the SD card I tested, the minimum block length is 512 */ +/* For MMC, the restriction is loose, due to the variety of SD and MMC +card support, ideally, the driver should read CSD register to find the +speed and block length for the card, and set them accordingly. */ +/* In this driver example, it will support both MMC and SD cards, it +does read the information by send SEND_CSD to poll the card status, +but, it doesn't configure them accordingly. this is not intended to +support all the SD and MMC card. */ + +/* DATA_BLOCK_LEN table + DATA_BLOCK_LEN Actual Size( BLOCK_LENGTH ) + 11 2048 + 10 1024 + 9 512 + 8 256 + 7 128 + 6 64 + 5 32 + 4 16 + 3 8 + 2 4 + 1 2 +*/ +/* This is the size of the buffer of origin data */ +#define MCI_DMA_SIZE (1000UL) +/* This is the area original data is stored or data to be written to the SD/MMC card. */ +#define MCI_DMA_SRC_ADDR LPC_PERI_RAM_BASE +/* This is the area, after reading from the SD/MMC*/ +#define MCI_DMA_DST_ADDR (MCI_DMA_SRC_ADDR + MCI_DMA_SIZE) + + +/* To simplify the programming, please note that, BLOCK_LENGTH is a multiple +of FIFO_SIZE */ +#define DATA_BLOCK_LEN (9) /* Block size field in DATA_CTRL */ +#define BLOCK_LENGTH (1 << DATA_BLOCK_LEN) + /* for SD card, 128, the size of the flash */ + /* card is 512 * 128 = 64K */ +#define BLOCK_NUM 0x80 +#define FIFO_SIZE 16 + +#define BUS_WIDTH_1BIT 0 +#define BUS_WIDTH_4BITS 10 + +/* MCI Status register bit information */ +#define MCI_CMD_CRC_FAIL (1 << 0) +#define MCI_DATA_CRC_FAIL (1 << 1) +#define MCI_CMD_TIMEOUT (1 << 2) +#define MCI_DATA_TIMEOUT (1 << 3) +#define MCI_TX_UNDERRUN (1 << 4) +#define MCI_RX_OVERRUN (1 << 5) +#define MCI_CMD_RESP_END (1 << 6) +#define MCI_CMD_SENT (1 << 7) +#define MCI_DATA_END (1 << 8) +#define MCI_START_BIT_ERR (1 << 9) +#define MCI_DATA_BLK_END (1 << 10) +#define MCI_CMD_ACTIVE (1 << 11) +#define MCI_TX_ACTIVE (1 << 12) +#define MCI_RX_ACTIVE (1 << 13) +#define MCI_TX_HALF_EMPTY (1 << 14) +#define MCI_RX_HALF_FULL (1 << 15) +#define MCI_TX_FIFO_FULL (1 << 16) +#define MCI_RX_FIFO_FULL (1 << 17) +#define MCI_TX_FIFO_EMPTY (1 << 18) +#define MCI_RX_FIFO_EMPTY (1 << 19) +#define MCI_TX_DATA_AVAIL (1 << 20) +#define MCI_RX_DATA_AVAIL (1 << 21) + + +/*********************************************************************** + * MCI Data control register definitions + **********************************************************************/ +/** Data transfer enable */ +#define MCI_DATACTRL_ENABLE_POS (0) +#define MCI_DATACTRL_ENABLE_MASK (0x01) +#define MCI_DATACTRL_ENABLE (1 << MCI_DATACTRL_ENABLE_POS) +#define MCI_DATACTRL_DISABLE (0 << MCI_DATACTRL_ENABLE_POS) + +/** Data transfer direction */ +#define MCI_DATACTRL_DIR_POS (1) +#define MCI_DATACTRL_DIR_MASK (0x01) +#define MCI_DATACTRL_DIR_FROM_CARD (1 << MCI_DATACTRL_DIR_POS) +#define MCI_DATACTRL_DIR_TO_CARD (0 << MCI_DATACTRL_DIR_POS) + + +/** Data transfer mode */ +#define MCI_DATACTRL_XFER_MODE_POS (2) +#define MCI_DATACTRL_XFER_MODE_MASK (0x01) +#define MCI_DATACTRL_XFER_MODE_STREAM (1 << MCI_DATACTRL_XFER_MODE_POS) +#define MCI_DATACTRL_XFER_MODE_BLOCK (0 << MCI_DATACTRL_XFER_MODE_POS) + +/** Enable DMA */ +#define MCI_DATACTRL_DMA_ENABLE_POS (3) +#define MCI_DATACTRL_DMA_ENABLE_MASK (0x01) +#define MCI_DATACTRL_DMA_ENABLE (1 << MCI_DATACTRL_DMA_ENABLE_POS) +#define MCI_DATACTRL_DMA_DISABLE (0 << MCI_DATACTRL_DMA_ENABLE_POS) + +/** Data block length macro */ +#define MCI_DTATCTRL_BLOCKSIZE(n) _SBF(4, (n & 0xF)) + + +#define CMD_INT_MASK (MCI_CMD_CRC_FAIL | MCI_CMD_TIMEOUT | MCI_CMD_RESP_END \ + | MCI_CMD_SENT | MCI_CMD_ACTIVE) + +#define DATA_ERR_INT_MASK (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_TX_UNDERRUN \ + | MCI_RX_OVERRUN | MCI_START_BIT_ERR) + +#define ACTIVE_INT_MASK ( MCI_TX_ACTIVE | MCI_RX_ACTIVE) + +#define FIFO_INT_MASK (MCI_TX_HALF_EMPTY | MCI_RX_HALF_FULL \ + | MCI_TX_FIFO_FULL | MCI_RX_FIFO_FULL \ + | MCI_TX_FIFO_EMPTY | MCI_RX_FIFO_EMPTY \ + | MCI_DATA_BLK_END ) + +#define FIFO_TX_INT_MASK (MCI_TX_HALF_EMPTY ) +#define FIFO_RX_INT_MASK (MCI_RX_HALF_FULL ) + +#define DATA_END_INT_MASK (MCI_DATA_END | MCI_DATA_BLK_END) + +#define ERR_TX_INT_MASK (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_TX_UNDERRUN | MCI_START_BIT_ERR) +#define ERR_RX_INT_MASK (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_RX_OVERRUN | MCI_START_BIT_ERR) + +/* Error code on the command response. */ +#define INVALID_RESPONSE 0xFFFFFFFF + +/** + * @} + */ + + +/** @defgroup MCI_Public_Types MCI Public Types + * @{ + */ + +typedef enum mci_card_state +{ + MCI_CARDSTATE_IDLE = 0, + MCI_CARDSTATE_READY, + MCI_CARDSTATE_IDENDTIFIED, + MCI_CARDSTATE_STBY, + MCI_CARDSTATE_TRAN, + MCI_CARDSTATE_DATA, + MCI_CARDSTATE_RCV, + MCI_CARDSTATE_PRG, + MCI_CARDSTATE_DIS, +}en_Mci_CardState; + + +typedef enum mci_func_error +{ + MCI_FUNC_OK = 0, + MCI_FUNC_FAILED = -1, + MCI_FUNC_BAD_PARAMETERS = -2, + MCI_FUNC_BUS_NOT_IDLE = -3, + MCI_FUNC_TIMEOUT = -3, + MCI_FUNC_ERR_STATE = -4, + MCI_FUNC_NOT_READY = -5, +}en_Mci_Func_Error; + +typedef enum mci_card_type +{ + MCI_SDHC_SDXC_CARD = 3, + MCI_SDSC_V2_CARD = 2, + MCI_MMC_CARD = 1, + MCI_SDSC_V1_CARD = 0, + MCI_CARD_UNKNOWN = -1, +}en_Mci_CardType; + +typedef struct mci_cid +{ + /** Manufacturer ID */ + uint8_t MID; + /** OEM/Application ID */ + uint16_t OID; + /** Product name 8-bits higher */ + uint8_t PNM_H; + /** Product name 32-bits Lower */ + uint32_t PNM_L; + /** Product revision */ + uint8_t PRV; + /** Product serial number */ + uint32_t PSN; + /** reserved: 4 bit */ + uint8_t reserved; + /** Manufacturing date: 12 bit */ + uint16_t MDT; + /** CRC7 checksum: 7 bit */ + uint8_t CRC; + /** not used, always: 1 bit always 1 */ + uint8_t unused; +} st_Mci_CardId; + +typedef struct cmd_info{ + /** Command ID*/ + uint32_t CmdIndex; + /** Command Argument*/ + uint32_t Argument; + /** Expected response: no response, short response or long response */ + uint32_t ExpectResp; + /** Allow timeout */ + uint32_t AllowTimeout; + /** Command Response Info */ + uint32_t *CmdResp; +} st_Mci_CmdInfo; +/** + * @} + */ + + +/** @defgroup MCI_Public_Functions MCI Public Functions + * @{ + */ + +int32_t MCI_Init(uint8_t powerActiveLevel ); +void MCI_SendCmd( st_Mci_CmdInfo* pCmdIf ); +int32_t MCI_GetCmdResp( uint32_t CmdIndex, uint32_t NeedRespFlag, uint32_t *CmdRespStatus ); +int32_t MCI_CmdResp(st_Mci_CmdInfo *pCmdIf); + +void MCI_Set_MCIClock( uint32_t clockrate ); +int32_t MCI_SetBusWidth( uint32_t width ); +int32_t MCI_Acmd_SendOpCond(uint8_t hcsVal); +int32_t MCI_CardInit( void ); +en_Mci_CardType MCI_GetCardType(void); +int32_t MCI_CardReset( void ); +int32_t MCI_Cmd_SendIfCond(void); +int32_t MCI_GetCID(st_Mci_CardId* cidValue); +int32_t MCI_SetCardAddress( void ); +uint32_t MCI_GetCardAddress(void); +int32_t MCI_GetCSD(uint32_t* csdVal); +int32_t MCI_Cmd_SelectCard( void ); +int32_t MCI_GetCardStatus(int32_t* cardStatus); +uint32_t MCI_GetDataXferEndState(void); +uint32_t MCI_GetXferErrState(void); +int32_t MCI_SetBlockLen( uint32_t blockLength ); +int32_t MCI_Acmd_SendBusWidth( uint32_t buswidth ); +int32_t MCI_Cmd_StopTransmission( void ); + +int32_t MCI_Cmd_WriteBlock(uint32_t blockNum, uint32_t numOfBlock); +int32_t MCI_Cmd_ReadBlock(uint32_t blockNum, uint32_t numOfBlock); + +int32_t MCI_WriteBlock(volatile uint8_t* memblock, uint32_t blockNum, uint32_t numOfBlock); +int32_t MCI_ReadBlock(volatile uint8_t* destBlock, uint32_t blockNum, uint32_t numOfBlock); +#if MCI_DMA_ENABLED +void MCI_DMA_IRQHandler (void); +#endif + +/** + * @} + */ + +#endif /* end __LPC_MCI_H_ */ + +/** + * @} + */ + +/**************************************************************************** +** End Of File +****************************************************************************/ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_mcpwm.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_mcpwm.h new file mode 100644 index 0000000000000000000000000000000000000000..008c4ed615983f461791c4ae099d6287389a0933 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_mcpwm.h @@ -0,0 +1,348 @@ +/********************************************************************** +* $Id$ lpc_mcpwm.h 2011-06-02 +*//** +* @file lpc_mcpwm.h +* @brief Contains all macro definitions and function prototypes +* support for Motor Control PWM firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup MCPWM MCPWM (Motor Control PWM) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_MCPWM_H_ +#define __LPC_MCPWM_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup MCPWM_Public_Macros MCPWM Public Macros + * @{ + */ + +/** Edge aligned mode for channel in MCPWM */ +#define MCPWM_CHANNEL_EDGE_MODE ((uint32_t)(0)) + +/** Center aligned mode for channel in MCPWM */ +#define MCPWM_CHANNEL_CENTER_MODE ((uint32_t)(1)) + +/** Polarity of the MCOA and MCOB pins: Passive state is LOW, active state is HIGH */ +#define MCPWM_CHANNEL_PASSIVE_LO ((uint32_t)(0)) +/** Polarity of the MCOA and MCOB pins: Passive state is HIGH, active state is LOW */ +#define MCPWM_CHANNEL_PASSIVE_HI ((uint32_t)(1)) + +/* Output Patent in 3-phase DC mode, the internal MCOA0 signal is routed to any or all of + * the six output pins under the control of the bits in this register */ +#define MCPWM_PATENT_A0 ((uint32_t)(1<<0)) /**< MCOA0 tracks internal MCOA0 */ +#define MCPWM_PATENT_B0 ((uint32_t)(1<<1)) /**< MCOB0 tracks internal MCOA0 */ +#define MCPWM_PATENT_A1 ((uint32_t)(1<<2)) /**< MCOA1 tracks internal MCOA0 */ +#define MCPWM_PATENT_B1 ((uint32_t)(1<<3)) /**< MCOB1 tracks internal MCOA0 */ +#define MCPWM_PATENT_A2 ((uint32_t)(1<<4)) /**< MCOA2 tracks internal MCOA0 */ +#define MCPWM_PATENT_B2 ((uint32_t)(1<<5)) /**< MCOB2 tracks internal MCOA0 */ + +/* Interrupt type in MCPWM */ +/** Limit interrupt for channel (0) */ +#define MCPWM_INTFLAG_LIM0 MCPWM_INT_ILIM(0) +/** Match interrupt for channel (0) */ +#define MCPWM_INTFLAG_MAT0 MCPWM_INT_IMAT(0) +/** Capture interrupt for channel (0) */ +#define MCPWM_INTFLAG_CAP0 MCPWM_INT_ICAP(0) + +/** Limit interrupt for channel (1) */ +#define MCPWM_INTFLAG_LIM1 MCPWM_INT_ILIM(1) +/** Match interrupt for channel (1) */ +#define MCPWM_INTFLAG_MAT1 MCPWM_INT_IMAT(1) +/** Capture interrupt for channel (1) */ +#define MCPWM_INTFLAG_CAP1 MCPWM_INT_ICAP(1) + +/** Limit interrupt for channel (2) */ +#define MCPWM_INTFLAG_LIM2 MCPWM_INT_ILIM(2) +/** Match interrupt for channel (2) */ +#define MCPWM_INTFLAG_MAT2 MCPWM_INT_IMAT(2) +/** Capture interrupt for channel (2) */ +#define MCPWM_INTFLAG_CAP2 MCPWM_INT_ICAP(2) + +/** Fast abort interrupt */ +#define MCPWM_INTFLAG_ABORT MCPWM_INT_ABORT + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup MCPWM_Private_Macros MCPWM Private Macros + * @{ + */ + +/*********************************************************************//** + * Macro defines for MCPWM Control register + **********************************************************************/ +/* MCPWM Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Control read address + * - MCPWM Control set address + * - MCPWM Control clear address + */ +/** Stops/starts timer channel n */ +#define MCPWM_CON_RUN(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*8)+0))) : (0)) +/** Edge/center aligned operation for channel n */ +#define MCPWM_CON_CENTER(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*8)+1))) : (0)) +/** Select polarity of the MCOAn and MCOBn pin */ +#define MCPWM_CON_POLAR(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*8)+2))) : (0)) +/** Control the dead-time feature for channel n */ +#define MCPWM_CON_DTE(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*8)+3))) : (0)) +/** Enable/Disable update of functional register for channel n */ +#define MCPWM_CON_DISUP(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*8)+4))) : (0)) + +/** Control the polarity for all 3 channels */ +#define MCPWM_CON_INVBDC ((uint32_t)((uint32_t)1<<29)) +/** 3-phase AC mode select */ +#define MCPWM_CON_ACMODE ((uint32_t)((uint32_t)1<<30)) +/** 3-phase DC mode select */ +#define MCPWM_CON_DCMODE ((uint32_t)((uint32_t)1<<31)) + +/*********************************************************************//** + * Macro defines for MCPWM Capture Control register + **********************************************************************/ +/* Capture Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Capture Control read address + * - MCPWM Capture Control set address + * - MCPWM Capture control clear address + */ +/** Enables/Disable channel (cap) capture event on a rising edge on MCI(mci) */ +#define MCPWM_CAPCON_CAPMCI_RE(cap,mci) (((cap < MCPWM_MAX_CHANNEL)&&(mci < MCPWM_MAX_CHANNEL)) ? ((uint32_t)(1<<((cap*6)+(mci*2)+0))) : (0)) +/** Enables/Disable channel (cap) capture event on a falling edge on MCI(mci) */ +#define MCPWM_CAPCON_CAPMCI_FE(cap,mci) (((cap < MCPWM_MAX_CHANNEL)&&(mci < MCPWM_MAX_CHANNEL)) ? ((uint32_t)(1<<((cap*6)+(mci*2)+1))) : (0)) +/** TC(n) is reset by channel (n) capture event */ +#define MCPWM_CAPCON_RT(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<(18+(n)))) : (0)) +/** Hardware noise filter: channel (n) capture events are delayed */ +#define MCPWM_CAPCON_HNFCAP(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<(21+(n)))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Interrupt register + **********************************************************************/ +/* Interrupt registers, these macro definitions below can be applied for these + * register type: + * - MCPWM Interrupt Enable read address + * - MCPWM Interrupt Enable set address + * - MCPWM Interrupt Enable clear address + * - MCPWM Interrupt Flags read address + * - MCPWM Interrupt Flags set address + * - MCPWM Interrupt Flags clear address + */ +/** Limit interrupt for channel (n) */ +#define MCPWM_INT_ILIM(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*4)+0))) : (0)) +/** Match interrupt for channel (n) */ +#define MCPWM_INT_IMAT(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*4)+1))) : (0)) +/** Capture interrupt for channel (n) */ +#define MCPWM_INT_ICAP(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<((n*4)+2))) : (0)) + +/** Fast abort interrupt */ +#define MCPWM_INT_ABORT ((uint32_t)(1<<15)) + +/*********************************************************************//** + * Macro defines for MCPWM Count Control register + **********************************************************************/ +/* MCPWM Count Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Count Control read address + * - MCPWM Count Control set address + * - MCPWM Count Control clear address + */ +/** Counter(tc) advances on a rising edge on MCI(mci) pin */ +#define MCPWM_CNTCON_TCMCI_RE(tc,mci) (((tc < MCPWM_MAX_CHANNEL)&&(mci < MCPWM_MAX_CHANNEL)) ? ((uint32_t)(1<<((6*tc)+(2*mci)+0))) : (0)) +/** Counter(cnt) advances on a falling edge on MCI(mci) pin */ +#define MCPWM_CNTCON_TCMCI_FE(tc,mci) (((tc < MCPWM_MAX_CHANNEL)&&(mci < MCPWM_MAX_CHANNEL)) ? ((uint32_t)(1<<((6*tc)+(2*mci)+1))) : (0)) +/** Channel (n) is in counter mode */ +#define MCPWM_CNTCON_CNTR(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<<(29+n))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Dead-time register + **********************************************************************/ +/** Dead time value x for channel n */ +#define MCPWM_DT(n,x) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)((x&0x3FF)<<(n*10))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Communication Pattern register + **********************************************************************/ +#define MCPWM_CP_A0 ((uint32_t)(1<<0)) /**< MCOA0 tracks internal MCOA0 */ +#define MCPWM_CP_B0 ((uint32_t)(1<<1)) /**< MCOB0 tracks internal MCOA0 */ +#define MCPWM_CP_A1 ((uint32_t)(1<<2)) /**< MCOA1 tracks internal MCOA0 */ +#define MCPWM_CP_B1 ((uint32_t)(1<<3)) /**< MCOB1 tracks internal MCOA0 */ +#define MCPWM_CP_A2 ((uint32_t)(1<<4)) /**< MCOA2 tracks internal MCOA0 */ +#define MCPWM_CP_B2 ((uint32_t)(1<<5)) /**< MCOB2 tracks internal MCOA0 */ + +/*********************************************************************//** + * Macro defines for MCPWM Capture clear address register + **********************************************************************/ +/** Clear the MCCAP (n) register */ +#define MCPWM_CAPCLR_CAP(n) ((n < MCPWM_MAX_CHANNEL) ? ((uint32_t)(1<>8)&0x07) +#define RTC_ER_EV2_COUNTER(n) ((n>>16)&0x07) + +/********************************************************************** +* Event Monitor/Recorder TimeStamp register +**********************************************************************/ +#define RTC_ER_TIMESTAMP_SEC(n) (n&0x3F) +#define RTC_ER_TIMESTAMP_MIN(n) ((n>>6)&0x3F) +#define RTC_ER_TIMESTAMP_HOUR(n) ((n>>12)&0x1F) +#define RTC_ER_TIMESTAMP_DOY(n) ((n>>17)&0x1FF) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup RTC_Public_Types RTC Public Types + * @{ + */ + +/** @brief Time structure definitions for easy manipulate the data */ +typedef struct +{ + /** Seconds Register */ + uint32_t SEC; + /** Minutes Register */ + uint32_t MIN; + /** Hours Register */ + uint32_t HOUR; + /** Day of Month Register */ + uint32_t DOM; + /** Day of Week Register */ + uint32_t DOW; + /** Day of Year Register */ + uint32_t DOY; + /** Months Register */ + uint32_t MONTH; + /** Years Register */ + uint32_t YEAR; +} RTC_TIME_Type; + +/** @brief RTC interrupt source */ +typedef enum +{ + /** Counter Increment Interrupt */ + RTC_INT_COUNTER_INCREASE = RTC_IRL_RTCCIF, + /** The alarm interrupt */ + RTC_INT_ALARM = RTC_IRL_RTCALF, +} RTC_INT_OPT; + + +/** @brief RTC time type option */ +typedef enum +{ + /** Second */ + RTC_TIMETYPE_SECOND = 0, + /** Month */ + RTC_TIMETYPE_MINUTE = 1, + /** Hour */ + RTC_TIMETYPE_HOUR = 2, + /** Day of week */ + RTC_TIMETYPE_DAYOFWEEK = 3, + /** Day of month */ + RTC_TIMETYPE_DAYOFMONTH = 4, + /** Day of year */ + RTC_TIMETYPE_DAYOFYEAR = 5, + /** Month */ + RTC_TIMETYPE_MONTH = 6, + /** Year */ + RTC_TIMETYPE_YEAR = 7, +} RTC_TIMETYPE_Num; + +/** @brief Event Monitor/Recording Input Channel configuration */ +typedef struct +{ + Bool EventOnPosEdge; // Event occurs on positive edge on the channel + Bool IntWake; // Create interrupt and wake-up request if there is an event + Bool GPClear; // Clear GP registers of RTC if there is an event. +} RTC_ER_CHANNEL_Init_Type; + +/** @brief Event Monitor/Recording configuration */ +typedef struct +{ + RTC_ER_CHANNEL_Init_Type InputChannel[RTC_ER_INPUT_CHANNEL_NUM]; + uint32_t Clk; // Sample clock on input channel. (Hz) +} RTC_ER_CONFIG_Type; + +/** @brief Event Monitor/Recording TimeStamp Type */ +typedef struct +{ + /** Seconds Register */ + uint32_t SEC; + /** Minutes Register */ + uint32_t MIN; + /** Hours Register */ + uint32_t HOUR; + /** Day of Year Register */ + uint32_t DOY; +} RTC_ER_TIMESTAMP_Type; + + +/** + * @} + */ + + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup RTC_Public_Functions RTC Public Functions + * @{ + */ + +void RTC_Init (LPC_RTC_TypeDef *RTCx); +void RTC_DeInit(LPC_RTC_TypeDef *RTCx); +void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx); +void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState); +void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \ + FunctionalState NewState); +void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \ + FunctionalState NewState); +void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue); +uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype); +void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue); +uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype); +void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType); +void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType); +void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState); +void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir); +void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value); +uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel); + +void RTC_ER_InitConfigStruct(RTC_ER_CONFIG_Type* pConfig); +Status RTC_ER_Init(RTC_ER_CONFIG_Type* pConfig); +Status RTC_ER_Cmd(uint8_t channel, FunctionalState state); +uint8_t RTC_ER_GetEventCount(uint8_t channel); +uint32_t RTC_ER_GetStatus(void); +Bool RTC_ER_WakupReqPending(void); +Bool RTC_ER_GPCleared(void); +Status RTC_ER_GetFirstTimeStamp(uint8_t channel, RTC_ER_TIMESTAMP_Type* pTimeStamp); +Status RTC_ER_GetLastTimeStamp(uint8_t channel, RTC_ER_TIMESTAMP_Type* pTimeStamp); +void RTC_ER_ClearStatus(uint32_t status); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_RTC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_spifi_rom_api.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_spifi_rom_api.h new file mode 100644 index 0000000000000000000000000000000000000000..1dec3f644c82981ab1b5018b877cd004aba1abd0 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_spifi_rom_api.h @@ -0,0 +1,248 @@ +/*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef SPIFI_ROM_API_H +#define SPIFI_ROM_API_H + +#include +/* define the symbol TESTING in the environment if test output desired */ + +/* maintain LONGEST_PROT >= the length (in bytes) of the largest + protection block of any serial flash that this driver handles */ +#define LONGEST_PROT 68 + +typedef uint8_t uc; + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* protection/sector descriptors */ +typedef struct { + uint32_t base; + uc flags; + int8_t log2; + uint16_t rept; +} protEnt; +/* bits in the flags byte */ +enum {RWPROT=1}; + +/* overall data structure includes # sectors, length of protection reg, + array of descriptors +typedef struct { + uint16_t sectors; + uint16_t protBytes; + protEnt *entries; +} protDesc; */ + +typedef union { + uint16_t hw; + uc byte[2]; +}stat_t; +/* the object that init returns, and other routines use as an operand */ +typedef struct { + uint32_t base, regbase, devSize, memSize; + uc mfger, devType, devID, busy; + stat_t stat; + uint16_t reserved; + uint16_t set_prot, write_prot; + uint32_t mem_cmd, prog_cmd; + uint16_t sectors, protBytes; + uint32_t opts, errCheck; + uc erase_shifts[4], erase_ops[4]; + protEnt *protEnts; + char prot[LONGEST_PROT]; +} SPIFIobj; + +/* operands of program and erase */ +typedef struct { + char *dest; + uint32_t length; + char *scratch; + int32_t protect; + uint32_t options; +} SPIFIopers; + +/* instruction classes for wait_busy */ +typedef enum {stat_inst, block_erase, prog_inst, chip_erase} inst_type; + +/* bits in options operands (MODE3, RCVCLK, and FULLCLK + have the same relationship as in the Control register) */ +#define S_MODE3 1 +#define S_MODE0 0 +#define S_MINIMAL 2 +#define S_MAXIMAL 0 +#define S_FORCE_ERASE 4 +#define S_ERASE_NOT_REQD 8 +#define S_CALLER_ERASE 8 +#define S_ERASE_AS_REQD 0 +#define S_VERIFY_PROG 0x10 +#define S_VERIFY_ERASE 0x20 +#define S_NO_VERIFY 0 +#define S_RCVCLK 0x80 +#define S_INTCLK 0 +#define S_FULLCLK 0x40 +#define S_HALFCLK 0 +#define S_DUAL 0x100 +#define S_CALLER_PROT 0x200 +#define S_DRIVER_PROT 0 + +/* the following values in the first post-address memory command byte work + for all known quad devices that support "no opcode" operation */ +#define NO_OPCODE_FOLLOWS 0xA5 +#define OPCODE_FOLLOWS 0xFF + +/* basic SPI commands for serial flash */ +#define BASE_READ_CMD (CMD_RD<opts (mostly for setMulti) */ +/* used by Winbond: send 0xA3 command so hardware can read faster */ +#define OPT_SEND_A3 1 +/* used by SST: send 0x38 command to enable quad and allow full command set */ +#define OPT_SEND_38 2 +/* used by Winbond and others: read status reg 2, check it, + if necessary write it back with Quad Enable set */ +#define OPT_35_OR02_01 4 +/* used by Atmel: read Configuration register, if necessary set Quad Enable */ +#define OPT_3F_OR80_3E 8 +/* used by Numonyx to set all-quad mode: only for parts that include RSTQIO */ +#define OPT_65_CLR_C0_61 0x10 +/* used by Numonyx: send 0x81 command to write Volatile Configuration Register + to set # dummy bytes and allow XIP mode */ +#define OPT_81 0x20 +/* set for devices without full device erase command (Numonyx type 0x40) */ +#define OPT_NO_DEV_ERASE 0x40 +/* used by Macronix: status reg 2 includes selection between write-protect + in status reg and command-based */ +#define OPT_WPSEL 0x80 +/* set when protection data has been read into the SPIFI object */ +#define OPT_PROT_READ 0x100 +/* set if device needs 4-byte address (and maybe 0x4B command = use 4-byte address) */ +#define OPT_4BAD 0x200 +/* set if setMulti should set the Dual bit in Control reg */ +#define OPT_DUAL 0x400 +/* send "# dummy bits" in C0 command to Winbond */ +#define OPT_C0 0x800 +/* set QE for Chingis */ +#define OPT_05_OR40_01 0x1000 +/* write status does not go busy */ +#define OPT_01_NO_BUSY 0x2000 +/* protection mode bits moved from protMode byte to opts Fri May 13 2011 */ +#define OPT_PROT_STAT 0x4000 +#define OPT_PROT_REG 0x8000 +#define OPT_PROT_CMD3 0x10000 +#define OPT_PROT_CMDE 0x20000 +#define OPT_PROT_MASK 0x3C000 + +#define OPT_ALL_QUAD 0x40000 + +#ifndef OMIT_ROM_TABLE +/* interface to ROM API */ +typedef struct { + int32_t (*spifi_init) (SPIFIobj *obj, uint32_t csHigh, uint32_t options, + uint32_t mhz); + int32_t (*spifi_program) (SPIFIobj *obj, char *source, SPIFIopers *opers); + int32_t (*spifi_erase) (SPIFIobj *obj, SPIFIopers *opers); + /* mode switching */ + void (*cancel_mem_mode)(SPIFIobj *obj); + void (*set_mem_mode) (SPIFIobj *obj); + + /* mid level functions */ + int32_t (*checkAd) (SPIFIobj *obj, SPIFIopers *opers); + int32_t (*setProt) (SPIFIobj *obj, SPIFIopers *opers, char *change, + char *saveProt); + int32_t (*check_block) (SPIFIobj *obj, char *source, SPIFIopers *opers, + uint32_t check_program); + int32_t (*send_erase_cmd) (SPIFIobj *obj, uint8_t op, uint32_t addr); + uint32_t (*ck_erase) (SPIFIobj *obj, uint32_t *addr, uint32_t length); + int32_t (*prog_block) (SPIFIobj *obj, char *source, SPIFIopers *opers, + uint32_t *left_in_page); + uint32_t (*ck_prog) (SPIFIobj *obj, char *source, char *dest, uint32_t length); + + /* low level functions */ + void(*setSize) (SPIFIobj *obj, int32_t value); + int32_t (*setDev) (SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd, + uint32_t prog_cmd); + uint32_t (*cmd) (uc op, uc addrLen, uc intLen, uint16_t len); + uint32_t (*readAd) (SPIFIobj *obj, uint32_t cmd, uint32_t addr); + void (*send04) (SPIFIobj *obj, uc op, uc len, uint32_t value); + void (*wren_sendAd) (SPIFIobj *obj, uint32_t cmd, uint32_t addr, uint32_t value); + int32_t (*write_stat) (SPIFIobj *obj, uc len, uint16_t value); + int32_t (*wait_busy) (SPIFIobj *obj, uc prog_or_erase); +} SPIFI_RTNS; + +#define define_spifi_romPtr(name) const SPIFI_RTNS *name=*((SPIFI_RTNS **)SPIFI_ROM_PTR) +#endif /* OMIT_ROM_TABLE */ + +#ifdef USE_SPIFI_LIB +extern SPIFI_RTNS spifi_table; +#endif /* USE_SPIFI_LIB */ + +/* example of using this interface: +#include "spifi_rom_api.h" +#define CSHIGH 4 +#define SPIFI_MHZ 80 +#define source_data_ad (char *)1234 + + int32_t rc; + SPIFIopers opers; + + define_spifi_romPtr(spifi); + SPIFIobj *obj = malloc(sizeof(SPIFIobj)); + if (!obj) { can't allocate memory } + + rc = spifi->spifi_init (obj, CSHIGH, S_FULLCLK+S_RCVCLK, SPIFI_MHZ); + if (rc) { investigate init error rc } + printf ("the serial flash contains %d bytes\n", obj->devSize); + + opers.dest = where_to_program; + opers.length = how_many_bytes; + opers.scratch = NULL; // unprogrammed data is not saved/restored + opers.protect = -1; // save & restore protection + opers.options = S_VERIFY_PROG; + + rc = spifi->spifi_program (obj, source_data_ad, &opers); + if (rc) { investigate program error rc } +*/ + +/* these are for normal users, including boot code */ +int32_t spifi_init (SPIFIobj *obj, uint32_t csHigh, uint32_t options, uint32_t mhz); +int32_t spifi_program (SPIFIobj *obj, char *source, SPIFIopers *opers); +int32_t spifi_erase (SPIFIobj *obj, SPIFIopers *opers); + +/* these are used by the manufacturer-specific init functions */ +void setSize (SPIFIobj *obj, int32_t value); +int32_t setDev (SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd, uint32_t prog_cmd); +uint32_t read04(SPIFIobj *obj, uc op, uc len); +int32_t write_stat (SPIFIobj *obj, uc len, uint16_t value); +void setProtEnts(SPIFIobj *obj, const protEnt *p, uint32_t protTabLen); + +/* needs to be defined for each platform */ +void pullMISO(int high); + +#ifdef TESTING +/* used by testing code */ +unsigned short getProtBytes (SPIFIobj *obj, unsigned short *sectors); +/* predeclare a debug routine */ +void wait_sample (volatile unsigned *addr, unsigned mask, unsigned value); +#endif + +#endif /* SPIFI_ROM_API_H */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_ssp.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..65e663d5bcf11f948f3197be9bcff6a1d6f0e60e --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_ssp.h @@ -0,0 +1,422 @@ +/********************************************************************** +* $Id$ lpc_ssp.h 2011-06-02 +*//** +* @file lpc_ssp.h +* @brief Contains all macro definitions and function prototypes +* support for SSP firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup SSP SSP (Synchronous Serial Port) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_SSP_H_ +#define __LPC_SSP_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup SSP_Public_Macros SSP Public Macros + * @{ + */ + +/*********************************************************************//** + * SSP configuration parameter defines + **********************************************************************/ +/** Clock phase control bit */ +#define SSP_CPHA_FIRST ((uint32_t)(0)) +#define SSP_CPHA_SECOND SSP_CR0_CPHA_SECOND + + +/** Clock polarity control bit */ +/* There's no bug here!!! + * - If bit[6] in SSPnCR0 is 0: SSP controller maintains the bus clock low between frames. + * That means the active clock is in HI state. + * - If bit[6] in SSPnCR0 is 1 (SSP_CR0_CPOL_HI): SSP controller maintains the bus clock + * high between frames. That means the active clock is in LO state. + */ +#define SSP_CPOL_HI ((uint32_t)(0)) +#define SSP_CPOL_LO SSP_CR0_CPOL_HI + +/** SSP master mode enable */ +#define SSP_SLAVE_MODE SSP_CR1_SLAVE_EN +#define SSP_MASTER_MODE ((uint32_t)(0)) + +/** SSP data bit number defines */ +#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */ +#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */ +#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */ +#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */ +#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */ +#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */ +#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */ +#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */ +#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */ +#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */ +#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */ +#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */ +#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */ + +/** SSP Frame Format definition */ +/** Motorola SPI mode */ +#define SSP_FRAME_SPI SSP_CR0_FRF_SPI +/** TI synchronous serial mode */ +#define SSP_FRAME_TI SSP_CR0_FRF_TI +/** National Micro-wire mode */ +#define SSP_FRAME_MICROWIRE SSP_CR0_FRF_MICROWIRE + +/*********************************************************************//** + * SSP Status defines + **********************************************************************/ +/** SSP status TX FIFO Empty bit */ +#define SSP_STAT_TXFIFO_EMPTY SSP_SR_TFE +/** SSP status TX FIFO not full bit */ +#define SSP_STAT_TXFIFO_NOTFULL SSP_SR_TNF +/** SSP status RX FIFO not empty bit */ +#define SSP_STAT_RXFIFO_NOTEMPTY SSP_SR_RNE +/** SSP status RX FIFO full bit */ +#define SSP_STAT_RXFIFO_FULL SSP_SR_RFF +/** SSP status SSP Busy bit */ +#define SSP_STAT_BUSY SSP_SR_BSY + +/*********************************************************************//** + * SSP Interrupt Configuration defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTCFG_ROR SSP_IMSC_ROR +/** Receive TimeOut */ +#define SSP_INTCFG_RT SSP_IMSC_RT +/** Rx FIFO is at least half full */ +#define SSP_INTCFG_RX SSP_IMSC_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTCFG_TX SSP_IMSC_TX + +/*********************************************************************//** + * SSP Configured Interrupt Status defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTSTAT_ROR SSP_MIS_ROR +/** Receive TimeOut */ +#define SSP_INTSTAT_RT SSP_MIS_RT +/** Rx FIFO is at least half full */ +#define SSP_INTSTAT_RX SSP_MIS_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTSTAT_TX SSP_MIS_TX + +/*********************************************************************//** + * SSP Raw Interrupt Status defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTSTAT_RAW_ROR SSP_RIS_ROR +/** Receive TimeOut */ +#define SSP_INTSTAT_RAW_RT SSP_RIS_RT +/** Rx FIFO is at least half full */ +#define SSP_INTSTAT_RAW_RX SSP_RIS_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTSTAT_RAW_TX SSP_RIS_TX + +/*********************************************************************//** + * SSP Interrupt Clear defines + **********************************************************************/ +/** Writing a 1 to this bit clears the "frame was received when + * RxFIFO was full" interrupt */ +#define SSP_INTCLR_ROR SSP_ICR_ROR +/** Writing a 1 to this bit clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt */ +#define SSP_INTCLR_RT SSP_ICR_RT + +/*********************************************************************//** + * SSP DMA defines + **********************************************************************/ +/** SSP bit for enabling RX DMA */ +#define SSP_DMA_RX SSP_DMA_RXDMA_EN +/** SSP bit for enabling TX DMA */ +#define SSP_DMA_TX SSP_DMA_TXDMA_EN + +/* SSP Status Implementation definitions */ +#define SSP_STAT_DONE (1UL<<8) /**< Done */ +#define SSP_STAT_ERROR (1UL<<9) /**< Error */ + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup SSP_Private_Macros SSP Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for CR0 register + **********************************************************************/ +/** SSP data size select, must be 4 bits to 16 bits */ +#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF)) +/** SSP control 0 Motorola SPI mode */ +#define SSP_CR0_FRF_SPI ((uint32_t)(0<<4)) +/** SSP control 0 TI synchronous serial mode */ +#define SSP_CR0_FRF_TI ((uint32_t)(1<<4)) +/** SSP control 0 National Micro-wire mode */ +#define SSP_CR0_FRF_MICROWIRE ((uint32_t)(2<<4)) +/** SPI clock polarity bit (used in SPI mode only), (1) = maintains the + bus clock high between frames, (0) = low */ +#define SSP_CR0_CPOL_HI ((uint32_t)(1<<6)) +/** SPI clock out phase bit (used in SPI mode only), (1) = captures data + on the second clock transition of the frame, (0) = first */ +#define SSP_CR0_CPHA_SECOND ((uint32_t)(1<<7)) +/** SSP serial clock rate value load macro, divider rate is + PERIPH_CLK / (cpsr * (SCR + 1)) */ +#define SSP_CR0_SCR(n) ((uint32_t)((n&0xFF)<<8)) +/** SSP CR0 bit mask */ +#define SSP_CR0_BITMASK ((uint32_t)(0xFFFF)) + +/*********************************************************************//** + * Macro defines for CR1 register + **********************************************************************/ +/** SSP control 1 loopback mode enable bit */ +#define SSP_CR1_LBM_EN ((uint32_t)(1<<0)) +/** SSP control 1 enable bit */ +#define SSP_CR1_SSP_EN ((uint32_t)(1<<1)) +/** SSP control 1 slave enable */ +#define SSP_CR1_SLAVE_EN ((uint32_t)(1<<2)) +/** SSP control 1 slave out disable bit, disables transmit line in slave + mode */ +#define SSP_CR1_SO_DISABLE ((uint32_t)(1<<3)) +/** SSP CR1 bit mask */ +#define SSP_CR1_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro defines for DR register + **********************************************************************/ +/** SSP data bit mask */ +#define SSP_DR_BITMASK(n) ((n)&0xFFFF) + +/*********************************************************************//** + * Macro defines for SR register + **********************************************************************/ +/** SSP status TX FIFO Empty bit */ +#define SSP_SR_TFE ((uint32_t)(1<<0)) +/** SSP status TX FIFO not full bit */ +#define SSP_SR_TNF ((uint32_t)(1<<1)) +/** SSP status RX FIFO not empty bit */ +#define SSP_SR_RNE ((uint32_t)(1<<2)) +/** SSP status RX FIFO full bit */ +#define SSP_SR_RFF ((uint32_t)(1<<3)) +/** SSP status SSP Busy bit */ +#define SSP_SR_BSY ((uint32_t)(1<<4)) +/** SSP SR bit mask */ +#define SSP_SR_BITMASK ((uint32_t)(0x1F)) + +/*********************************************************************//** + * Macro defines for CPSR register + **********************************************************************/ +/** SSP clock prescaler */ +#define SSP_CPSR_CPDVSR(n) ((uint32_t)(n&0xFF)) +/** SSP CPSR bit mask */ +#define SSP_CPSR_BITMASK ((uint32_t)(0xFF)) + +/*********************************************************************//** + * Macro define for (IMSC) Interrupt Mask Set/Clear registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_IMSC_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_IMSC_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_IMSC_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_IMSC_TX ((uint32_t)(1<<3)) +/** IMSC bit mask */ +#define SSP_IMSC_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (RIS) Raw Interrupt Status registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_RIS_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_RIS_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_RIS_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_RIS_TX ((uint32_t)(1<<3)) +/** RIS bit mask */ +#define SSP_RIS_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (MIS) Masked Interrupt Status registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_MIS_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_MIS_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_MIS_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_MIS_TX ((uint32_t)(1<<3)) +/** MIS bit mask */ +#define SSP_MIS_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (ICR) Interrupt Clear registers + **********************************************************************/ +/** Writing a 1 to this bit clears the "frame was received when + * RxFIFO was full" interrupt */ +#define SSP_ICR_ROR ((uint32_t)(1<<0)) +/** Writing a 1 to this bit clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt */ +#define SSP_ICR_RT ((uint32_t)(1<<1)) +/** ICR bit mask */ +#define SSP_ICR_BITMASK ((uint32_t)(0x03)) + +/*********************************************************************//** + * Macro defines for DMACR register + **********************************************************************/ +/** SSP bit for enabling RX DMA */ +#define SSP_DMA_RXDMA_EN ((uint32_t)(1<<0)) +/** SSP bit for enabling TX DMA */ +#define SSP_DMA_TXDMA_EN ((uint32_t)(1<<1)) +/** DMACR bit mask */ +#define SSP_DMA_BITMASK ((uint32_t)(0x03)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup SSP_Public_Types SSP Public Types + * @{ + */ + +/** @brief SSP configuration structure */ +typedef struct { + uint32_t Databit; /** Databit number, should be SSP_DATABIT_x, + where x is in range from 4 - 16 */ + uint32_t CPHA; /** Clock phase, should be: + - SSP_CPHA_FIRST: first clock edge + - SSP_CPHA_SECOND: second clock edge */ + uint32_t CPOL; /** Clock polarity, should be: + - SSP_CPOL_HI: high level + - SSP_CPOL_LO: low level */ + uint32_t Mode; /** SSP mode, should be: + - SSP_MASTER_MODE: Master mode + - SSP_SLAVE_MODE: Slave mode */ + uint32_t FrameFormat; /** Frame Format: + - SSP_FRAME_SPI: Motorola SPI frame format + - SSP_FRAME_TI: TI frame format + - SSP_FRAME_MICROWIRE: National Microwire frame format */ + uint32_t ClockRate; /** Clock rate,in Hz */ +} SSP_CFG_Type; + +/** + * @brief SSP Transfer Type definitions + */ +typedef enum { + SSP_TRANSFER_POLLING = 0, /**< Polling transfer */ + SSP_TRANSFER_INTERRUPT /**< Interrupt transfer */ +} SSP_TRANSFER_Type; + +/** + * @brief SPI Data configuration structure definitions + */ +typedef struct { + void *tx_data; /**< Pointer to transmit data */ + uint32_t tx_cnt; /**< Transmit counter */ + void *rx_data; /**< Pointer to transmit data */ + uint32_t rx_cnt; /**< Receive counter */ + uint32_t length; /**< Length of transfer data */ + uint32_t status; /**< Current status of SSP activity */ +} SSP_DATA_SETUP_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup SSP_Public_Functions SSP Public Functions + * @{ + */ + +/* SSP Init/DeInit functions --------------------------------------------------*/ +void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct); +void SSP_DeInit(LPC_SSP_TypeDef* SSPx); + +/* SSP configure functions ----------------------------------------------------*/ +void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct); + +/* SSP enable/disable functions -----------------------------------------------*/ +void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState); + +/* SSP get information functions ----------------------------------------------*/ +FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType); +uint8_t SSP_GetDataSize(LPC_SSP_TypeDef* SSPx); +IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType); +uint32_t SSP_GetRawIntStatusReg(LPC_SSP_TypeDef *SSPx); +IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType); + +/* SSP transfer data functions ------------------------------------------------*/ +void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data); +uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx); +int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \ + SSP_TRANSFER_Type xfType); + +/* SSP IRQ function ------------------------------------------------------------*/ +void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState); +void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_SSP_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_systick.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_systick.h new file mode 100644 index 0000000000000000000000000000000000000000..cca57104e527eb13a2997763c79a353d9823dd2c --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_systick.h @@ -0,0 +1,119 @@ +/********************************************************************** +* $Id$ lpc_systick.h 2011-06-02 +*//** +* @file lpc_systick.h +* @brief Contains all macro definitions and function prototypes +* support for SYSTICK firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup SYSTICK SysTick (System tick timer) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_SYSTICK_H_ +#define __LPC_SYSTICK_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup SYSTICK_Private_Macros SysTick Private Macros + * @{ + */ +/*********************************************************************//** + * Macro defines for System Timer Control and status (STCTRL) register + **********************************************************************/ +#define ST_CTRL_ENABLE ((uint32_t)(1<<0)) +#define ST_CTRL_TICKINT ((uint32_t)(1<<1)) +#define ST_CTRL_CLKSOURCE ((uint32_t)(1<<2)) +#define ST_CTRL_COUNTFLAG ((uint32_t)(1<<16)) + +/*********************************************************************//** + * Macro defines for System Timer Reload value (STRELOAD) register + **********************************************************************/ +#define ST_RELOAD_RELOAD(n) ((uint32_t)(n & 0x00FFFFFF)) + +/*********************************************************************//** + * Macro defines for System Timer Current value (STCURRENT) register + **********************************************************************/ +#define ST_RELOAD_CURRENT(n) ((uint32_t)(n & 0x00FFFFFF)) + +/*********************************************************************//** + * Macro defines for System Timer Calibration value (STCALIB) register + **********************************************************************/ +#define ST_CALIB_TENMS(n) ((uint32_t)(n & 0x00FFFFFF)) +#define ST_CALIB_SKEW ((uint32_t)(1<<30)) +#define ST_CALIB_NOREF ((uint32_t)(1<<31)) + +#define CLKSOURCE_EXT ((uint32_t)(0)) +#define CLKSOURCE_CPU ((uint32_t)(1)) + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup SYSTICK_Public_Functions Systick Public Functions + * @{ + */ + +void SYSTICK_InternalInit(uint32_t time); +void SYSTICK_ExternalInit(uint32_t freq, uint32_t time); + +void SYSTICK_Cmd(FunctionalState NewState); +void SYSTICK_IntCmd(FunctionalState NewState); +uint32_t SYSTICK_GetCurrentValue(void); +void SYSTICK_ClearCounterFlag(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __LPC_SYSTICK_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_timer.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..acabdfc709089bd533060b5895fcebfd9ee81eb4 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_timer.h @@ -0,0 +1,321 @@ +/********************************************************************** +* $Id$ lpc_timer.h 2011-06-02 +*//** +* @file lpc_timer.h +* @brief Contains all macro definitions and function prototypes +* support for Timer firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup TIMER TIM (Timer) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_TIMER_H_ +#define __LPC_TIMER_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup TIM_Private_Macros Timer Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/********************************************************************** +** Interrupt information +**********************************************************************/ +/** Macro to clean interrupt pending */ +#define TIM_IR_CLR(n) _BIT(n) + +/********************************************************************** +** Timer interrupt register definitions +**********************************************************************/ +/** Macro for getting a timer match interrupt bit */ +#define TIM_MATCH_INT(n) (_BIT(n & 0x0F)) +/** Macro for getting a capture event interrupt bit */ +#define TIM_CAP_INT(n) (_BIT(((n & 0x0F) + 4))) + +/********************************************************************** +* Timer control register definitions +**********************************************************************/ +/** Timer/counter enable bit */ +#define TIM_ENABLE ((uint32_t)(1<<0)) +/** Timer/counter reset bit */ +#define TIM_RESET ((uint32_t)(1<<1)) +/** Timer control bit mask */ +#define TIM_TCR_MASKBIT ((uint32_t)(3)) + +/********************************************************************** +* Timer match control register definitions +**********************************************************************/ +/** Bit location for interrupt on MRx match, n = 0 to 3 */ +#define TIM_INT_ON_MATCH(n) (_BIT((n * 3))) +/** Bit location for reset on MRx match, n = 0 to 3 */ +#define TIM_RESET_ON_MATCH(n) (_BIT(((n * 3) + 1))) +/** Bit location for stop on MRx match, n = 0 to 3 */ +#define TIM_STOP_ON_MATCH(n) (_BIT(((n * 3) + 2))) +/** Timer Match control bit mask */ +#define TIM_MCR_MASKBIT ((uint32_t)(0x0FFF)) +/** Timer Match control bit mask for specific channel*/ +#define TIM_MCR_CHANNEL_MASKBIT(n) ((uint32_t)(7<<(n*3))) + +/********************************************************************** +* Timer capture control register definitions +**********************************************************************/ +/** Bit location for CAP.n on CRx rising edge, n = 0 to 3 */ +#define TIM_CAP_RISING(n) (_BIT((n * 3))) +/** Bit location for CAP.n on CRx falling edge, n = 0 to 3 */ +#define TIM_CAP_FALLING(n) (_BIT(((n * 3) + 1))) +/** Bit location for CAP.n on CRx interrupt enable, n = 0 to 3 */ +#define TIM_INT_ON_CAP(n) (_BIT(((n * 3) + 2))) +/** Mask bit for rising and falling edge bit */ +#define TIM_EDGE_MASK(n) (_SBF((n * 3), 0x03)) +/** Timer capture control bit mask */ +#define TIM_CCR_MASKBIT ((uint32_t)(0x3F)) +/** Timer Capture control bit mask for specific channel*/ +#define TIM_CCR_CHANNEL_MASKBIT(n) ((uint32_t)(7<<(n*3))) + +/********************************************************************** +* Timer external match register definitions +**********************************************************************/ +/** Bit location for output state change of MAT.n when external match + happens, n = 0 to 3 */ +#define TIM_EM(n) _BIT(n) +/** Output state change of MAT.n when external match happens: no change */ +#define TIM_EM_NOTHING ((uint8_t)(0x0)) +/** Output state change of MAT.n when external match happens: low */ +#define TIM_EM_LOW ((uint8_t)(0x1)) +/** Output state change of MAT.n when external match happens: high */ +#define TIM_EM_HIGH ((uint8_t)(0x2)) +/** Output state change of MAT.n when external match happens: toggle */ +#define TIM_EM_TOGGLE ((uint8_t)(0x3)) +/** Macro for setting for the MAT.n change state bits */ +#define TIM_EM_SET(n,s) (_SBF(((n << 1) + 4), (s & 0x03))) +/** Mask for the MAT.n change state bits */ +#define TIM_EM_MASK(n) (_SBF(((n << 1) + 4), 0x03)) +/** Timer external match bit mask */ +#define TIM_EMR_MASKBIT 0x0FFF + +/********************************************************************** +* Timer Count Control Register definitions +**********************************************************************/ +/** Mask to get the Counter/timer mode bits */ +#define TIM_CTCR_MODE_MASK 0x3 +/** Mask to get the count input select bits */ +#define TIM_CTCR_INPUT_MASK 0xC +/** Timer Count control bit mask */ +#define TIM_CTCR_MASKBIT 0xF +#define TIM_COUNTER_MODE ((uint8_t)(1)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup TIM_Public_Types Timer Public Types + * @{ + */ + +/*********************************************************************** + * Timer device enumeration +**********************************************************************/ +/** @brief interrupt type */ +typedef enum +{ + TIM_MR0_INT =0, /*!< interrupt for Match channel 0*/ + TIM_MR1_INT =1, /*!< interrupt for Match channel 1*/ + TIM_MR2_INT =2, /*!< interrupt for Match channel 2*/ + TIM_MR3_INT =3, /*!< interrupt for Match channel 3*/ + TIM_CR0_INT =4, /*!< interrupt for Capture channel 0*/ + TIM_CR1_INT =5, /*!< interrupt for Capture channel 1*/ +}TIM_INT_TYPE; + +/** @brief Timer/counter operating mode */ +typedef enum +{ + TIM_TIMER_MODE = 0, /*!< Timer mode */ + TIM_COUNTER_RISING_MODE, /*!< Counter rising mode */ + TIM_COUNTER_FALLING_MODE, /*!< Counter falling mode */ + TIM_COUNTER_ANY_MODE /*!< Counter on both edges */ +} TIM_MODE_OPT; + +/** @brief Timer/Counter prescale option */ +typedef enum +{ + TIM_PRESCALE_TICKVAL = 0, /*!< Prescale in absolute value */ + TIM_PRESCALE_USVAL /*!< Prescale in microsecond value */ +} TIM_PRESCALE_OPT; + +/** @brief Counter input option */ +typedef enum +{ + TIM_COUNTER_INCAP0 = 0, /*!< CAPn.0 input pin for TIMERn */ + TIM_COUNTER_INCAP1, /*!< CAPn.1 input pin for TIMERn */ +} TIM_COUNTER_INPUT_OPT; + +/** @brief Timer/Counter external match option */ +typedef enum +{ + TIM_EXTMATCH_NOTHING = 0, /*!< Do nothing for external output pin if match */ + TIM_EXTMATCH_LOW, /*!< Force external output pin to low if match */ + TIM_EXTMATCH_HIGH, /*!< Force external output pin to high if match */ + TIM_EXTMATCH_TOGGLE /*!< Toggle external output pin if match */ +}TIM_EXTMATCH_OPT; + +/** @brief Timer/counter capture mode options */ +typedef enum { + TIM_CAPTURE_NONE = 0, /*!< No Capture */ + TIM_CAPTURE_RISING, /*!< Rising capture mode */ + TIM_CAPTURE_FALLING, /*!< Falling capture mode */ + TIM_CAPTURE_ANY /*!< On both edges */ +} TIM_CAP_MODE_OPT; + +/** @brief Configuration structure in TIMER mode */ +typedef struct +{ + + uint8_t PrescaleOption; /**< Timer Prescale option, should be: + - TIM_PRESCALE_TICKVAL: Prescale in absolute value + - TIM_PRESCALE_USVAL: Prescale in microsecond value + */ + uint8_t Reserved[3]; /**< Reserved */ + uint32_t PrescaleValue; /**< Prescale value */ +} TIM_TIMERCFG_Type; + +/** @brief Configuration structure in COUNTER mode */ +typedef struct { + + uint8_t CounterOption; /**< Counter Option, should be: + - TIM_COUNTER_INCAP0: CAPn.0 input pin for TIMERn + - TIM_COUNTER_INCAP1: CAPn.1 input pin for TIMERn + */ + uint8_t CountInputSelect; + uint8_t Reserved[2]; +} TIM_COUNTERCFG_Type; + +/** @brief Match channel configuration structure */ +typedef struct { + uint8_t MatchChannel; /**< Match channel, should be in range + from 0..3 */ + uint8_t IntOnMatch; /**< Interrupt On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t StopOnMatch; /**< Stop On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t ResetOnMatch; /**< Reset On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + + uint8_t ExtMatchOutputType; /**< External Match Output type, should be: + - TIM_EXTMATCH_NOTHING: Do nothing for external output pin if match + - TIM_EXTMATCH_LOW: Force external output pin to low if match + - TIM_EXTMATCH_HIGH: Force external output pin to high if match + - TIM_EXTMATCH_TOGGLE: Toggle external output pin if match. + */ + uint8_t Reserved[3]; /** Reserved */ + uint32_t MatchValue; /** Match value */ +} TIM_MATCHCFG_Type; + +/** @brief Capture Input configuration structure */ +typedef struct { + uint8_t CaptureChannel; /**< Capture channel, should be in range + from 0..1 */ + uint8_t RisingEdge; /**< caption rising edge, should be: + - ENABLE: Enable rising edge. + - DISABLE: Disable this function. + */ + uint8_t FallingEdge; /**< caption falling edge, should be: + - ENABLE: Enable falling edge. + - DISABLE: Disable this function. + */ + uint8_t IntOnCaption; /**< Interrupt On caption, should be: + - ENABLE: Enable interrupt function. + - DISABLE: Disable this function. + */ + +} TIM_CAPTURECFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup TIM_Public_Functions Timer Public Functions + * @{ + */ +/* Init/DeInit TIM functions -----------*/ +void TIM_Init(LPC_TIM_TypeDef *TIMx, TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct); +void TIM_DeInit(LPC_TIM_TypeDef *TIMx); + +/* TIM interrupt functions -------------*/ +void TIM_ClearIntPending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +void TIM_ClearIntCapturePending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +FlagStatus TIM_GetIntStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +FlagStatus TIM_GetIntCaptureStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); + +/* TIM configuration functions --------*/ +void TIM_ConfigStructInit(TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct); +void TIM_ConfigMatch(LPC_TIM_TypeDef *TIMx, TIM_MATCHCFG_Type *TIM_MatchConfigStruct); +void TIM_UpdateMatchValue(LPC_TIM_TypeDef *TIMx,uint8_t MatchChannel, uint32_t MatchValue); +void TIM_ConfigCapture(LPC_TIM_TypeDef *TIMx, TIM_CAPTURECFG_Type *TIM_CaptureConfigStruct); +void TIM_Cmd(LPC_TIM_TypeDef *TIMx, FunctionalState NewState); + +uint32_t TIM_GetCaptureValue(LPC_TIM_TypeDef *TIMx, TIM_COUNTER_INPUT_OPT CaptureChannel); +void TIM_ResetCounter(LPC_TIM_TypeDef *TIMx); + +void TIM_Waitus(uint32_t time); +void TIM_Waitms(uint32_t time); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_TIMER_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_types.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..72639dc6c53fb529e37e5192b5656341a64f28c9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_types.h @@ -0,0 +1,211 @@ +/********************************************************************** +* $Id$ lpc_types.h 2011-06-02 +*//** +* @file lpc_types.h +* @brief Contains the NXP ABL typedefs for C standard types. +* It is intended to be used in ISO C conforming development +* environments and checks for this insofar as it is possible +* to do so. +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Type group ----------------------------------------------------------- */ +#ifndef __LPC_TYPES_H +#define __LPC_TYPES_H + +/* Includes ------------------------------------------------------------------- */ +#include + +/** @defgroup LPC_Type_Def Data Types Definitions + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup LPC_Types_Public_Types Basic Public Data Types + * @{ + */ + +/** + * @brief Boolean Type definition + */ +typedef enum {FALSE = 0, TRUE = !FALSE} Bool; + +/** + * @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_Type; + + +/** 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)(); + +/** + * @} + */ + + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup LPC_Types_Public_Macros Basic 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< = (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_Types Public Types + * @{ + */ + +/** SMA type for character type */ +typedef char CHAR; + +/** SMA type for 8 bit unsigned value */ +typedef uint8_t UNS_8; + +/** SMA type for 8 bit signed value */ +typedef int8_t INT_8; + +/** SMA type for 16 bit unsigned value */ +typedef uint16_t UNS_16; + +/** SMA type for 16 bit signed value */ +typedef int16_t INT_16; + +/** SMA type for 32 bit unsigned value */ +typedef uint32_t UNS_32; + +/** SMA type for 32 bit signed value */ +typedef int32_t INT_32; + +/** SMA type for 64 bit signed value */ +typedef int64_t INT_64; + +/** SMA type for 64 bit unsigned value */ +typedef uint64_t UNS_64; + +/** 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 /* __LPC_TYPES_H */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/include/lpc_uart.h b/bsp/lpc408x/Libraries/Drivers/include/lpc_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..f54f08dc1c7bcacc67d4f66e077127d941aba498 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/include/lpc_uart.h @@ -0,0 +1,710 @@ +/********************************************************************** +* $Id$ lpc_uart.h 2011-06-02 +*//** +* @file lpc_uart.h +* @brief Contains all macro definitions and function prototypes +* support for UART firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup UART UART (Universal Asynchronous Receiver/Transmitter) + * @ingroup LPC_CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC_UART_H_ +#define __LPC_UART_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup UART_Public_Macros UART Public Macros + * @{ + */ + +/** UART time-out definitions in case of using Read() and Write function + * with Blocking Flag mode + */ +#define UART_BLOCKING_TIMEOUT (0xFFFFFFFFUL) + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ + +/* Accepted Error baud rate value (in percent unit) */ +#define UART_ACCEPTED_BAUDRATE_ERROR (3) /*!< Acceptable UART baudrate error */ + + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Receiver Buffer Register + **********************************************************************/ +/** UART Received Buffer mask bit (8 bits) */ +#define UART_RBR_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Transmit Holding Register + **********************************************************************/ +/** UART Transmit Holding mask bit (8 bits) */ +#define UART_THR_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Divisor Latch LSB register + **********************************************************************/ +/** Macro for loading least significant halfs of divisors */ +#define UART_LOAD_DLL(div) ((div) & 0xFF) +/** Divisor latch LSB bit mask */ +#define UART_DLL_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Divisor Latch MSB register + **********************************************************************/ +/** Divisor latch MSB bit mask */ +#define UART_DLM_MASKBIT ((uint8_t)0xFF) +/** Macro for loading most significant halfs of divisors */ +#define UART_LOAD_DLM(div) (((div) >> 8) & 0xFF) + +/*********************************************************************//** + * Macro defines for Macro defines for UART interrupt enable register + **********************************************************************/ +/** RBR Interrupt enable*/ +#define UART_IER_RBRINT_EN ((uint32_t)(1<<0)) +/** THR Interrupt enable*/ +#define UART_IER_THREINT_EN ((uint32_t)(1<<1)) +/** RX line status interrupt enable*/ +#define UART_IER_RLSINT_EN ((uint32_t)(1<<2)) +/** Modem status interrupt enable */ +#define UART1_IER_MSINT_EN ((uint32_t)(1<<3)) +/** CTS1 signal transition interrupt enable */ +#define UART1_IER_CTSINT_EN ((uint32_t)(1<<7)) +/** Enables the end of auto-baud interrupt */ +#define UART_IER_ABEOINT_EN ((uint32_t)(1<<8)) +/** Enables the auto-baud time-out interrupt */ +#define UART_IER_ABTOINT_EN ((uint32_t)(1<<9)) +/** UART interrupt enable register bit mask */ +#define UART_IER_BITMASK ((uint32_t)(0x307)) +/** UART1 interrupt enable register bit mask */ +#define UART1_IER_BITMASK ((uint32_t)(0x38F)) + + +/*********************************************************************//** + * Macro defines for Macro defines for UART interrupt identification register + **********************************************************************/ +/** Interrupt Status - Active low */ +#define UART_IIR_INTSTAT_PEND ((uint32_t)(1<<0)) +/** Interrupt identification: Receive line status*/ +#define UART_IIR_INTID_RLS ((uint32_t)(3<<1)) +/** Interrupt identification: Receive data available*/ +#define UART_IIR_INTID_RDA ((uint32_t)(2<<1)) +/** Interrupt identification: Character time-out indicator*/ +#define UART_IIR_INTID_CTI ((uint32_t)(6<<1)) +/** Interrupt identification: THRE interrupt*/ +#define UART_IIR_INTID_THRE ((uint32_t)(1<<1)) +/** Interrupt identification: Modem interrupt*/ +#define UART1_IIR_INTID_MODEM ((uint32_t)(0<<1)) +/** Interrupt identification: Interrupt ID mask */ +#define UART_IIR_INTID_MASK ((uint32_t)(7<<1)) +/** These bits are equivalent to UnFCR[0] */ +#define UART_IIR_FIFO_EN ((uint32_t)(3<<6)) +/** End of auto-baud interrupt */ +#define UART_IIR_ABEO_INT ((uint32_t)(1<<8)) +/** Auto-baud time-out interrupt */ +#define UART_IIR_ABTO_INT ((uint32_t)(1<<9)) +/** UART interrupt identification register bit mask */ +#define UART_IIR_BITMASK ((uint32_t)(0x3CF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART FIFO control register + **********************************************************************/ +/** UART FIFO enable */ +#define UART_FCR_FIFO_EN ((uint8_t)(1<<0)) +/** UART FIFO RX reset */ +#define UART_FCR_RX_RS ((uint8_t)(1<<1)) +/** UART FIFO TX reset */ +#define UART_FCR_TX_RS ((uint8_t)(1<<2)) +/** UART DMA mode selection */ +#define UART_FCR_DMAMODE_SEL ((uint8_t)(1<<3)) +/** UART FIFO trigger level 0: 1 character */ +#define UART_FCR_TRG_LEV0 ((uint8_t)(0)) +/** UART FIFO trigger level 1: 4 character */ +#define UART_FCR_TRG_LEV1 ((uint8_t)(1<<6)) +/** UART FIFO trigger level 2: 8 character */ +#define UART_FCR_TRG_LEV2 ((uint8_t)(2<<6)) +/** UART FIFO trigger level 3: 14 character */ +#define UART_FCR_TRG_LEV3 ((uint8_t)(3<<6)) +/** UART FIFO control bit mask */ +#define UART_FCR_BITMASK ((uint8_t)(0xCF)) + +#define UART_TX_FIFO_SIZE (16) + +/*********************************************************************//** + * Macro defines for Macro defines for UART line control register + **********************************************************************/ +/** UART 5 bit data mode */ +#define UART_LCR_WLEN5 ((uint8_t)(0)) +/** UART 6 bit data mode */ +#define UART_LCR_WLEN6 ((uint8_t)(1<<0)) +/** UART 7 bit data mode */ +#define UART_LCR_WLEN7 ((uint8_t)(2<<0)) +/** UART 8 bit data mode */ +#define UART_LCR_WLEN8 ((uint8_t)(3<<0)) +/** UART Two Stop Bits Select */ +#define UART_LCR_STOPBIT_SEL ((uint8_t)(1<<2)) +/** UART Parity Enable */ +#define UART_LCR_PARITY_EN ((uint8_t)(1<<3)) +/** UART Odd Parity Select */ +#define UART_LCR_PARITY_ODD ((uint8_t)(0)) +/** UART Even Parity Select */ +#define UART_LCR_PARITY_EVEN ((uint8_t)(1<<4)) +/** UART force 1 stick parity */ +#define UART_LCR_PARITY_F_1 ((uint8_t)(2<<4)) +/** UART force 0 stick parity */ +#define UART_LCR_PARITY_F_0 ((uint8_t)(3<<4)) +/** UART Transmission Break enable */ +#define UART_LCR_BREAK_EN ((uint8_t)(1<<6)) +/** UART Divisor Latches Access bit enable */ +#define UART_LCR_DLAB_EN ((uint8_t)(1<<7)) +/** UART line control bit mask */ +#define UART_LCR_BITMASK ((uint8_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 Modem Control Register + **********************************************************************/ +/** Source for modem output pin DTR */ +#define UART1_MCR_DTR_CTRL ((uint8_t)(1<<0)) +/** Source for modem output pin RTS */ +#define UART1_MCR_RTS_CTRL ((uint8_t)(1<<1)) +/** Loop back mode select */ +#define UART1_MCR_LOOPB_EN ((uint8_t)(1<<4)) +/** Enable Auto RTS flow-control */ +#define UART1_MCR_AUTO_RTS_EN ((uint8_t)(1<<6)) +/** Enable Auto CTS flow-control */ +#define UART1_MCR_AUTO_CTS_EN ((uint8_t)(1<<7)) +/** UART1 bit mask value */ +#define UART1_MCR_BITMASK ((uint8_t)(0x0F3)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART line status register + **********************************************************************/ +/** Line status register: Receive data ready*/ +#define UART_LSR_RDR ((uint8_t)(1<<0)) +/** Line status register: Overrun error*/ +#define UART_LSR_OE ((uint8_t)(1<<1)) +/** Line status register: Parity error*/ +#define UART_LSR_PE ((uint8_t)(1<<2)) +/** Line status register: Framing error*/ +#define UART_LSR_FE ((uint8_t)(1<<3)) +/** Line status register: Break interrupt*/ +#define UART_LSR_BI ((uint8_t)(1<<4)) +/** Line status register: Transmit holding register empty*/ +#define UART_LSR_THRE ((uint8_t)(1<<5)) +/** Line status register: Transmitter empty*/ +#define UART_LSR_TEMT ((uint8_t)(1<<6)) +/** Error in RX FIFO*/ +#define UART_LSR_RXFE ((uint8_t)(1<<7)) +/** UART Line status bit mask */ +#define UART_LSR_BITMASK ((uint8_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART Modem (UART1 only) status register + **********************************************************************/ +/** Set upon state change of input CTS */ +#define UART1_MSR_DELTA_CTS ((uint8_t)(1<<0)) +/** Set upon state change of input DSR */ +#define UART1_MSR_DELTA_DSR ((uint8_t)(1<<1)) +/** Set upon low to high transition of input RI */ +#define UART1_MSR_LO2HI_RI ((uint8_t)(1<<2)) +/** Set upon state change of input DCD */ +#define UART1_MSR_DELTA_DCD ((uint8_t)(1<<3)) +/** Clear To Send State */ +#define UART1_MSR_CTS ((uint8_t)(1<<4)) +/** Data Set Ready State */ +#define UART1_MSR_DSR ((uint8_t)(1<<5)) +/** Ring Indicator State */ +#define UART1_MSR_RI ((uint8_t)(1<<6)) +/** Data Carrier Detect State */ +#define UART1_MSR_DCD ((uint8_t)(1<<7)) +/** MSR register bit-mask value */ +#define UART1_MSR_BITMASK ((uint8_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART Scratch Pad Register + **********************************************************************/ +/** UART Scratch Pad bit mask */ +#define UART_SCR_BIMASK ((uint8_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART Auto baudrate control register + **********************************************************************/ +/** UART Auto-baud start */ +#define UART_ACR_START ((uint32_t)(1<<0)) +/** UART Auto baudrate Mode 1 */ +#define UART_ACR_MODE ((uint32_t)(1<<1)) +/** UART Auto baudrate restart */ +#define UART_ACR_AUTO_RESTART ((uint32_t)(1<<2)) +/** UART End of auto-baud interrupt clear */ +#define UART_ACR_ABEOINT_CLR ((uint32_t)(1<<8)) +/** UART Auto-baud time-out interrupt clear */ +#define UART_ACR_ABTOINT_CLR ((uint32_t)(1<<9)) +/** UART Auto Baudrate register bit mask */ +#define UART_ACR_BITMASK ((uint32_t)(0x307)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART IrDA control register + **********************************************************************/ +/** IrDA mode enable */ +#define UART_ICR_IRDAEN ((uint32_t)(1<<0)) +/** IrDA serial input inverted */ +#define UART_ICR_IRDAINV ((uint32_t)(1<<1)) +/** IrDA fixed pulse width mode */ +#define UART_ICR_FIXPULSE_EN ((uint32_t)(1<<2)) +/** PulseDiv - Configures the pulse when FixPulseEn = 1 */ +#define UART_ICR_PULSEDIV(n) ((uint32_t)((n&0x07)<<3)) +/** UART IRDA bit mask */ +#define UART_ICR_BITMASK ((uint32_t)(0x3F)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART Fractional divider register + **********************************************************************/ +/** Baud-rate generation pre-scaler divisor */ +#define UART_FDR_DIVADDVAL(n) ((uint32_t)(n&0x0F)) +/** Baud-rate pre-scaler multiplier value */ +#define UART_FDR_MULVAL(n) ((uint32_t)((n<<4)&0xF0)) +/** UART Fractional Divider register bit mask */ +#define UART_FDR_BITMASK ((uint32_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART Tx Enable register + **********************************************************************/ +/** Transmit enable bit */ +#define UART_TER_TXEN ((uint8_t)(1<<7)) +/** UART Transmit Enable Register bit mask */ +#define UART_TER_BITMASK ((uint8_t)(0x80)) +/** Transmit enable bit on UART4 */ +#define UART4_TER_TXEN ((uint8_t)(1<<0)) +/** UART4 Transmit Enable Register bit mask */ +#define UART4_TER_BITMASK ((uint8_t)(0x01)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART RS485 Control register + **********************************************************************/ +/** RS-485/EIA-485 Normal Multi-drop Mode (NMM) is disabled */ +#define UART_RS485CTRL_NMM_EN ((uint32_t)(1<<0)) +/** The receiver is disabled */ +#define UART_RS485CTRL_RX_DIS ((uint32_t)(1<<1)) +/** Auto Address Detect (AAD) is enabled */ +#define UART_RS485CTRL_AADEN ((uint32_t)(1<<2)) +/** If direction control is enabled (bit DCTRL = 1), pin DTR is used for direction control */ +#define UART_RS485CTRL_SEL_DTR ((uint32_t)(1<<3)) +/** Enable Auto Direction Control */ +#define UART_RS485CTRL_DCTRL_EN ((uint32_t)(1<<4)) +/** This bit reverses the polarity of the direction control signal on the RTS (or DTR) pin. +The direction control pin will be driven to logic "1" when the transmitter has data to be sent */ +#define UART_RS485CTRL_OINV_1 ((uint32_t)(1<<5)) + +/** RS485 control bit-mask value */ +#define UART_RS485CTRL_BITMASK ((uint32_t)(0x3F)) + +/*********************************************************************//** + * Macro defines for Macro defines for UART RS-485 Address Match register + **********************************************************************/ +#define UART_RS485ADRMATCH_BITMASK ((uint8_t)(0xFF)) /**< Bit mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 RS-485 Delay value register + **********************************************************************/ +/* Macro defines for UART1 RS-485 Delay value register */ +#define UART_RS485DLY_BITMASK ((uint8_t)(0xFF)) /** Bit mask value */ + + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup UART_Public_Types UART Public Types + * @{ + */ + +/** + * @brief UART ID + */ + typedef enum +{ + UART_0 = 0, + UART_1, + UART_2, + UART_3, + UART_4, +} UART_ID_Type; + +/** + * @brief UART Databit type definitions + */ +typedef enum { + UART_DATABIT_5 = 0, /*!< UART 5 bit data mode */ + UART_DATABIT_6, /*!< UART 6 bit data mode */ + UART_DATABIT_7, /*!< UART 7 bit data mode */ + UART_DATABIT_8 /*!< UART 8 bit data mode */ +} UART_DATABIT_Type; + +/** + * @brief UART Stop bit type definitions + */ +typedef enum { + UART_STOPBIT_1 = (0), /*!< UART 1 Stop Bits Select */ + UART_STOPBIT_2, /*!< UART Two Stop Bits Select */ +} UART_STOPBIT_Type; + +/** + * @brief UART Parity type definitions + */ +typedef enum { + UART_PARITY_NONE = 0, /*!< No parity */ + UART_PARITY_ODD, /*!< Odd parity */ + UART_PARITY_EVEN, /*!< Even parity */ + UART_PARITY_SP_1, /*!< Forced "1" stick parity */ + UART_PARITY_SP_0 /*!< Forced "0" stick parity */ +} UART_PARITY_Type; + +/** + * @brief FIFO Level type definitions + */ +typedef enum { + UART_FIFO_TRGLEV0 = 0, /*!< UART FIFO trigger level 0: 1 character */ + UART_FIFO_TRGLEV1, /*!< UART FIFO trigger level 1: 4 character */ + UART_FIFO_TRGLEV2, /*!< UART FIFO trigger level 2: 8 character */ + UART_FIFO_TRGLEV3 /*!< UART FIFO trigger level 3: 14 character */ +} UART_FITO_LEVEL_Type; + +/********************************************************************//** +* @brief UART Interrupt Type definitions +**********************************************************************/ +typedef enum { + UART_INTCFG_RBR = 0, /*!< RBR Interrupt enable*/ + UART_INTCFG_THRE, /*!< THR Interrupt enable*/ + UART_INTCFG_RLS, /*!< RX line status interrupt enable*/ + UART_INTCFG_MS, /*!< Modem status interrupt enable (UART1 only) */ + UART_INTCFG_CTS, /*!< CTS1 signal transition interrupt enable (UART1 only) */ + UART_INTCFG_ABEO, /*!< Enables the end of auto-baud interrupt */ + UART_INTCFG_ABTO /*!< Enables the auto-baud time-out interrupt */ +} UART_INT_Type; + +/** + * @brief UART Line Status Type definition + */ +typedef enum { + UART_LINESTAT_RDR = UART_LSR_RDR, /*! the enable bit is enabled */ + uint8_t wdtReset; /**< if ENABLE -> the Reset bit is enabled */ + uint8_t wdtProtect; /**< if ENABLE -> the Protect bit is enabled */ + uint32_t wdtTmrConst; /**< Set the constant value to timeout the WDT */ + uint32_t wdtWarningVal; /**< Set the value to warn the WDT with interrupt */ + uint32_t wdtWindowVal; /**< Set a window vaule for WDT */ +}st_Wdt_Config; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup WDT_Public_Functions WDT Public Functions + * @{ + */ + +int8_t WWDT_Init(uint32_t TimeOut); +int8_t WWDT_Start(uint32_t TimeOut); +void WWDT_SetMode(uint8_t mode, FunctionalState NewState); +void WWDT_SetTimerConstant(uint32_t constVal); +void WWDT_Enable(FunctionalState NewState); +void WWDT_Cmd(FunctionalState NewState); +int8_t WWDT_SetWarningRaw(uint32_t warnVal); +int8_t WWDT_SetWarning(uint32_t WarnTime); +int8_t WWDT_SetWindowRaw(uint32_t wndVal); +int8_t WWDT_SetWindow(uint32_t WindowedTime); +void WWDT_UpdateTimeOut(uint32_t TimeOut); +FlagStatus WWDT_GetStatus (uint8_t Status); +void WWDT_ClearStatusFlag (uint8_t flag); +void WWDT_ClrTimeOutFlag (void); +void WWDT_FeedStdSeq (void); +void WWDT_Feed (void); +uint32_t WWDT_GetCurrentCount(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC_WWDT_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/lib/spifi_drv_M4.lib b/bsp/lpc408x/Libraries/Drivers/lib/spifi_drv_M4.lib new file mode 100644 index 0000000000000000000000000000000000000000..0a9c0e2e44351947188a502f411abe27a6ca5acb Binary files /dev/null and b/bsp/lpc408x/Libraries/Drivers/lib/spifi_drv_M4.lib differ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_adc.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..19a2a2d99f691cda06b3b59b1d93f79d440b07e2 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_adc.c @@ -0,0 +1,326 @@ +/********************************************************************** +* $Id$ lpc_adc.c 2011-06-02 +*//** +* @file lpc_adc.c +* @brief Contains all functions support for ADC firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup ADC + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _ADC + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_types.h" +#include "lpc_adc.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup ADC_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Initial for ADC + * + Set bit PCADC + * + Set clock for ADC + * + Set Clock Frequency + * @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC + * @param[in] rate ADC conversion rate, should be <=200KHz + * @return None + **********************************************************************/ +void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate) +{ + uint32_t ADCPClk, temp, tmp; + + // Turn on power and clock + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCADC, ENABLE); + + ADCx->CR = 0; + + //Enable PDN bit + tmp = ADC_CR_PDN; + + // Set clock frequency + ADCPClk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + /* The APB clock (PCLK_ADC0) is divided by (CLKDIV+1) to produce the clock for + * A/D converter, which should be less than or equal to 12.4MHz. + * A fully conversion requires 31 of these clocks. + * ADC clock = PCLK_ADC0 / (CLKDIV + 1); + * ADC rate = ADC clock / 31; + */ + temp = rate * 31; + temp = (ADCPClk * 2 + temp)/(2 * temp) - 1; //get the round value by fomular: (2*A + B)/(2*A) + tmp |= ADC_CR_CLKDIV(temp); + + ADCx->CR = tmp; +} + + +/*********************************************************************//** +* @brief Close ADC +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @return None +**********************************************************************/ +void ADC_DeInit(LPC_ADC_TypeDef *ADCx) +{ + if (ADCx->CR & ADC_CR_START_MASK) //need to stop START bits before DeInit + ADCx->CR &= ~ADC_CR_START_MASK; + // Clear SEL bits + ADCx->CR &= ~0xFF; + + // Clear PDN bit + ADCx->CR &= ~ADC_CR_PDN; + // Turn on power and clock + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCADC, DISABLE); +} + + +/*********************************************************************//** +* @brief Get Result conversion from A/D data register +* @param[in] channel number which want to read back the result +* @return Result of conversion +*********************************************************************/ +uint32_t ADC_GetData(uint32_t channel) +{ + uint32_t adc_value; + + adc_value = *(uint32_t *)((&LPC_ADC->DR[0]) + channel); + return ADC_GDR_RESULT(adc_value); +} + +/*********************************************************************//** +* @brief Set start mode for ADC +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] start_mode Start mode choose one of modes in +* 'ADC_START_OPT' enumeration type definition, should be: +* - ADC_START_CONTINUOUS +* - ADC_START_NOW +* - ADC_START_ON_EINT0 +* - ADC_START_ON_CAP01 +* - ADC_START_ON_MAT01 +* - ADC_START_ON_MAT03 +* - ADC_START_ON_MAT10 +* - ADC_START_ON_MAT11 +* @return None +*********************************************************************/ +void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode) +{ + ADCx->CR &= ~ADC_CR_START_MASK; + ADCx->CR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode); +} + + +/*********************************************************************//** +* @brief ADC Burst mode setting +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] NewState +* - 1: Set Burst mode +* - 0: reset Burst mode +* @return None +**********************************************************************/ +void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState) +{ + ADCx->CR &= ~ADC_CR_BURST; + if (NewState){ + ADCx->CR |= ADC_CR_BURST; + } +} + +/*********************************************************************//** +* @brief Set AD conversion in power mode +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] NewState +* - 1: AD converter is optional +* - 0: AD Converter is in power down mode +* @return None +**********************************************************************/ +void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState) +{ + ADCx->CR &= ~ADC_CR_PDN; + if (NewState){ + ADCx->CR |= ADC_CR_PDN; + } +} + +/*********************************************************************//** +* @brief Set Edge start configuration +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING +* 0:ADC_START_ON_RISING +* 1:ADC_START_ON_FALLING +* @return None +**********************************************************************/ +void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption) +{ + ADCx->CR &= ~ADC_CR_EDGE; + if (EdgeOption){ + ADCx->CR |= ADC_CR_EDGE; + } +} + +/*********************************************************************//** +* @brief ADC interrupt configuration +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] IntType: type of interrupt, should be: +* - ADC_ADINTEN0: Interrupt channel 0 +* - ADC_ADINTEN1: Interrupt channel 1 +* ... +* - ADC_ADINTEN7: Interrupt channel 7 +* - ADC_ADGINTEN: Individual channel/global flag done generate an interrupt +* @param[in] NewState: +* - SET : enable ADC interrupt +* - RESET: disable ADC interrupt +* @return None +**********************************************************************/ +void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState) +{ + ADCx->INTEN &= ~ADC_INTEN_CH(IntType); + if (NewState){ + ADCx->INTEN |= ADC_INTEN_CH(IntType); + } +} + +/*********************************************************************//** +* @brief Enable/Disable ADC channel number +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] Channel channel number +* @param[in] NewState Enable or Disable +* +* @return None +**********************************************************************/ +void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState) +{ + if (NewState == ENABLE) { + ADCx->CR |= ADC_CR_CH_SEL(Channel); + } else { + if (ADCx->CR & ADC_CR_START_MASK) //need to stop START bits before disable channel + ADCx->CR &= ~ADC_CR_START_MASK; + ADCx->CR &= ~ADC_CR_CH_SEL(Channel); + } +} + +/*********************************************************************//** +* @brief Get ADC result +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] channel: channel number, should be 0...7 +* @return Data conversion +**********************************************************************/ +uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel) +{ + uint32_t adc_value; + adc_value = *(uint32_t *) ((&ADCx->DR[0]) + channel); + return ADC_DR_RESULT(adc_value); +} + +/*********************************************************************//** +* @brief Get ADC Chanel status from ADC data register +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] channel: channel number, should be 0..7 +* @param[in] StatusType +* 0:Burst status +* 1:Done status +* @return SET / RESET +**********************************************************************/ +FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType) +{ + uint32_t temp; + temp = *(uint32_t *) ((&ADCx->DR[0]) + channel); + if (StatusType) + { + temp &= ADC_DR_DONE_FLAG; + } + else + { + temp &= ADC_DR_OVERRUN_FLAG; + } + + if (temp) + { + return SET; + } + else + { + return RESET; + } + +} + +/*********************************************************************//** +* @brief Get ADC Data from AD Global register +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @return Result of conversion +**********************************************************************/ +uint32_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx) +{ + return ((uint32_t)(ADCx->GDR)); +} + +/*********************************************************************//** +* @brief Get ADC Chanel status from AD global data register +* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC +* @param[in] StatusType +* 0:Burst status +* 1:Done status +* @return SET / RESET +**********************************************************************/ +FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType) +{ + uint32_t temp; + + temp = ADCx->GDR; + if (StatusType){ + temp &= ADC_DR_DONE_FLAG; + }else{ + temp &= ADC_DR_OVERRUN_FLAG; + } + if (temp){ + return SET; + }else{ + return RESET; + } +} + +/** + * @} + */ +#endif /*_ADC*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_bod.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_bod.c new file mode 100644 index 0000000000000000000000000000000000000000..050d12ebdfb1046c877b9f03a05bf11746dd16fa --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_bod.c @@ -0,0 +1,119 @@ +/********************************************************************** +* $Id$ lpc_bod.c 2011-12-09 +*//** +* @file lpc_bod.c +* @brief Contain functions related to BOD. +* @version 1.0 +* @date 09 December. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup BOD + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _BOD +#include "LPC407x_8x_177x_8x.h" /* LPC407x_8x_177x_8x Peripheral Registers */ +#include "lpc_bod.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup BOD_Public_Functions + * @{ + */ +/*********************************************************************//** + * @brief Initialize BOD control register + * @param[in] pConfig BOD Configuration + * @return None + **********************************************************************/ +void BOD_Init( BOD_Config_Type* pConfig ) +{ + /* Turn on/off BOD. */ + if(pConfig->Enabled == DISABLE) + { + LPC_SC->PCON |= BOD_PCON_BOGD; + return; + } + LPC_SC->PCON &= ~BOD_PCON_BOGD; + + /* Brown-Out Reduced Power Mode */ + if(pConfig->PowerReduced == ENABLE) + { + LPC_SC->PCON |= BOD_PCON_BODRPM; + } + else + { + LPC_SC->PCON &= ~BOD_PCON_BODRPM; + } + + /* Brown-Out Reset */ + if(pConfig->ResetOnVoltageDown == DISABLE) + { + LPC_SC->PCON |= BOD_PCON_BORD; + } + else + { + LPC_SC->PCON &= ~BOD_PCON_BORD; + } + + /* Enable the BOD Interrupt */ + NVIC_EnableIRQ(BOD_IRQn); + + return; +} + + +/*********************************************************************//** + * @brief Get BOD reset source status + * @param[in] None + * @return TRUE/FALSE + **********************************************************************/ +int32_t BOD_ResetSourceStatus( void ) +{ + if((LPC_SC->RSID & BOD_RSID_POR) == 1) + return DISABLE; + return ((LPC_SC->RSID & BOD_RSID_BODR)? ENABLE:DISABLE); +} +/*********************************************************************//** + * @brief Clear BOD reset source bit + * @param[in] None + * @return None + **********************************************************************/ +void BOD_ResetSourceClr( void ) +{ + LPC_SC->RSID |= BOD_RSID_BODR; +} +/** + * @} + */ +#endif /*_BOD */ +/** + * @} + */ +/****************************************************************************** +** End Of File +******************************************************************************/ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_can.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_can.c new file mode 100644 index 0000000000000000000000000000000000000000..26776179e40f42eeb801ea45267305073af14bc9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_can.c @@ -0,0 +1,2197 @@ +/********************************************************************** +* $Id$ lpc_can.c 2011-06-02 +*//** +* @file lpc_can.c +* @brief Contains all functions support for CAN firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup CAN + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _CAN + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_can.h" +#include "lpc_clkpwr.h" + +/* Private Variables ---------------------------------------------------------- */ +/** @defgroup CAN_Private_Variables CAN Private Variables + * @{ + */ + +FunctionalState FULLCAN_ENABLE; + + +/* Counts number of filters (CAN message objects) used */ +uint16_t CANAF_FullCAN_cnt = 0; +uint16_t CANAF_std_cnt = 0; +uint16_t CANAF_gstd_cnt = 0; +uint16_t CANAF_ext_cnt = 0; +uint16_t CANAF_gext_cnt = 0; + +/* End of Private Variables ----------------------------------------------------*/ +/** + * @} + */ + +/* Private Variables ---------------------------------------------------------- */ +static LPC_CAN_TypeDef* CAN_GetPointer (uint8_t canId); + + +static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate); + +/*********************************************************************//** + * @brief Setting CAN baud rate (bps) + * @param[in] canId point to LPC_CAN_TypeDef object, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @return The pointer to CAN peripheral that's expected to use + ***********************************************************************/ +static LPC_CAN_TypeDef* CAN_GetPointer (uint8_t canId) +{ + LPC_CAN_TypeDef* pCan; + + switch (canId) + { + case CAN_ID_1: + pCan = LPC_CAN1; + break; + + case CAN_ID_2: + pCan = LPC_CAN2; + break; + + default: + pCan = NULL; + break; + } + + return pCan; +} + + +/*********************************************************************//** + * @brief Setting CAN baud rate (bps) + * @param[in] CANx point to LPC_CAN_TypeDef object, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] baudrate: is the baud rate value will be set + * @return None + ***********************************************************************/ +static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate) +{ + uint32_t result = 0; + uint8_t NT, TSEG1, TSEG2; + uint32_t CANPclk = 0; + uint32_t BRP; + + CANPclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + result = CANPclk / baudrate; + + /* Calculate suitable nominal time value + * NT (nominal time) = (TSEG1 + TSEG2 + 3) + * NT <= 24 + * TSEG1 >= 2*TSEG2 + */ + for(NT = 24; NT > 0; NT = NT-2) + { + if ((result%NT) == 0) + { + BRP = result / NT - 1; + + NT--; + + TSEG2 = (NT/3) - 1; + + TSEG1 = NT -(NT/3) - 1; + + break; + } + } + + /* Enter reset mode */ + CANx->MOD = 0x01; + + /* Set bit timing + * Default: SAM = 0x00; + * SJW = 0x03; + */ + CANx->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP; + + /* Return to normal operating */ + CANx->MOD = 0; +} +/* End of Private Functions ----------------------------------------------------*/ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup CAN_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initialize CAN peripheral with given baudrate + * @param[in] canId The Id of the expected CAN component + * + * @param[in] baudrate: the value of CAN baudrate will be set (bps) + * @return None + *********************************************************************/ +void CAN_Init(uint8_t canId, uint32_t baudrate) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + uint16_t i; + + if(canId == CAN_ID_1) + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE); + } + else if(canId == CAN_ID_2) + { + /* Turn on power and clock for CAN2 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE); + } + else + { + return; + } + + pCan->MOD = 1; // Enter Reset Mode + pCan->IER = 0; // Disable All CAN Interrupts + pCan->GSR = 0; + + /* Request command to release Rx, Tx buffer and clear data overrun */ + //pCan->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO; + pCan->CMR = (1 << 1) | (1 << 2) | (1 << 3); + + /* Read to clear interrupt pending in interrupt capture register */ + i = pCan->ICR; + pCan->MOD = 0;// Return Normal operating + + //Reset CANAF value + LPC_CANAF->AFMR = 0x01; + + //clear ALUT RAM + for (i = 0; i < 512; i++) + { + LPC_CANAF_RAM->mask[i] = 0x00; + } + + LPC_CANAF->SFF_sa = 0x00; + LPC_CANAF->SFF_GRP_sa = 0x00; + LPC_CANAF->EFF_sa = 0x00; + LPC_CANAF->EFF_GRP_sa = 0x00; + LPC_CANAF->ENDofTable = 0x00; + + LPC_CANAF->AFMR = 0x00; + + /* Set baudrate */ + can_SetBaudrate (pCan, baudrate); +} + +/********************************************************************//** + * @brief CAN deInit + * @param[in] canId The Id of the expected CAN component + * + * @return None + *********************************************************************/ +void CAN_DeInit(uint8_t canId) +{ + if(canId == CAN_ID_1) + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE); + } + else if(canId == CAN_ID_2) + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE); + } + + return; +} + +/********************************************************************//** + * @brief Setup Acceptance Filter Look-Up Table + * @param[in] CANAFx pointer to LPC_CANAF_TypeDef + * Should be: LPC_CANAF + * @param[in] AFSection the pointer to AF_SectionDef structure + * It contain information about 5 sections will be install in AFLUT + * @return CAN Error could be: + * - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available + * - CAN_AF_ENTRY_ERROR: table error-violation of ascending numerical order + * - CAN_OK: ID is added into table successfully + *********************************************************************/ +CAN_ERROR CAN_SetupAFLUT(AF_SectionDef* AFSection) +{ + uint8_t ctrl1,ctrl2; + uint8_t dis1, dis2; + uint16_t SID, ID_temp,i, count = 0; + uint32_t EID, entry, buf; + uint16_t lowerSID, upperSID; + uint32_t lowerEID, upperEID; + + LPC_CANAF->AFMR = 0x01; + + /***** setup FullCAN Table *****/ + if(AFSection->FullCAN_Sec == NULL) + { + FULLCAN_ENABLE = DISABLE; + } + else + { + FULLCAN_ENABLE = ENABLE; + + for(i = 0; i < (AFSection->FC_NumEntry); i++) + { + if(count + 1 > 64) + { + return CAN_OBJECTS_FULL_ERROR; + } + + ctrl1 = AFSection->FullCAN_Sec->controller; + + SID = AFSection->FullCAN_Sec->id_11; + + dis1 = AFSection->FullCAN_Sec->disable; + + entry = 0x00; //reset entry value + + if((CANAF_FullCAN_cnt & 0x00000001)==0) + { + if(count != 0x00) + { + buf = LPC_CANAF_RAM->mask[count-1]; + ID_temp = (buf & 0xE7FF); //mask controller & identifier bits + if(ID_temp > ((ctrl1<<13)|SID)) + { + return CAN_AF_ENTRY_ERROR; + } + } + + entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27); + + LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; + + LPC_CANAF_RAM->mask[count] |= entry; + + CANAF_FullCAN_cnt++; + if(CANAF_FullCAN_cnt == AFSection->FC_NumEntry) //this is the lastest FullCAN entry + count++; + } + else + { + buf = LPC_CANAF_RAM->mask[count]; + ID_temp = (buf >>16) & 0xE7FF; + if(ID_temp > ((ctrl1<<13)|SID)) + { + return CAN_AF_ENTRY_ERROR; + } + + entry = (ctrl1 << 13) | (dis1 << 12) | (SID << 0) | (1 << 11); + + LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; + + LPC_CANAF_RAM->mask[count]|= entry; + + count++; + + CANAF_FullCAN_cnt++; + } + + AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry)); + } + } + + /***** Setup Explicit Standard Frame Format Section *****/ + if(AFSection->SFF_Sec != NULL) + { + for(i=0;i<(AFSection->SFF_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + + ctrl1 = AFSection->SFF_Sec->controller; + + SID = AFSection->SFF_Sec->id_11; + + dis1 = AFSection->SFF_Sec->disable; + + entry = 0x00; //reset entry value + + if((CANAF_std_cnt & 0x00000001)==0) + { + if(CANAF_std_cnt !=0 ) + { + buf = LPC_CANAF_RAM->mask[count-1]; + ID_temp = (buf & 0xE7FF); //mask controller & identifier bits + if(ID_temp > ((ctrl1<<13)|SID)) + { + return CAN_AF_ENTRY_ERROR; + } + } + + entry = (ctrl1<<29)|(dis1<<28)|(SID<<16); + + LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; + + LPC_CANAF_RAM->mask[count] |= entry; + + CANAF_std_cnt++; + if(CANAF_std_cnt == AFSection->SFF_NumEntry)//if this is the last SFF entry + count++; + } + else + { + buf = LPC_CANAF_RAM->mask[count]; + ID_temp = (buf >>16) & 0xE7FF; + if(ID_temp > ((ctrl1<<13)|SID)) + { + return CAN_AF_ENTRY_ERROR; + } + + entry = (ctrl1 << 13) | (dis1 << 12) | (SID << 0); + + LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; + + LPC_CANAF_RAM->mask[count] |= entry; + + count++; + + CANAF_std_cnt++; + } + + AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry)); + } + } + + /***** Setup Group of Standard Frame Format Identifier Section *****/ + if(AFSection->SFF_GPR_Sec != NULL) + { + for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + + ctrl1 = AFSection->SFF_GPR_Sec->controller1; + + ctrl2 = AFSection->SFF_GPR_Sec->controller2; + + dis1 = AFSection->SFF_GPR_Sec->disable1; + + dis2 = AFSection->SFF_GPR_Sec->disable2; + + lowerSID = AFSection->SFF_GPR_Sec->lowerID; + + upperSID = AFSection->SFF_GPR_Sec->upperID; + + entry = 0x00; + + if(CANAF_gstd_cnt!=0) + { + buf = LPC_CANAF_RAM->mask[count-1]; + ID_temp = buf & 0xE7FF; + if((ctrl1 != ctrl2)||(lowerSID > upperSID)||(ID_temp > ((ctrl1<<13)|lowerSID))) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)| \ + (ctrl2 << 13)|(dis2 << 12)|(upperSID << 0); + LPC_CANAF_RAM->mask[count] = entry; + + CANAF_gstd_cnt++; + + count++; + + AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry)); + } + } + + /***** Setup Explicit Extend Frame Format Identifier Section *****/ + if(AFSection->EFF_Sec != NULL) + { + for(i=0;i<(AFSection->EFF_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + + EID = AFSection->EFF_Sec->ID_29; + + ctrl1 = AFSection->EFF_Sec->controller; + + entry = 0x00; //reset entry value + + entry = (ctrl1 << 29)|(EID << 0); + if(CANAF_ext_cnt != 0) + { + buf = LPC_CANAF_RAM->mask[count-1]; +// EID_temp = buf & 0x0FFFFFFF; + if(buf > entry) + { + return CAN_AF_ENTRY_ERROR; + } + } + LPC_CANAF_RAM->mask[count] = entry; + + CANAF_ext_cnt ++; + + count++; + + AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry)); + } + } + + /***** Setup Group of Extended Frame Format Identifier Section *****/ + if(AFSection->EFF_GPR_Sec != NULL) + { + for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++) + { + if(count + 2 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + + ctrl1 = AFSection->EFF_GPR_Sec->controller1; + + ctrl2 = AFSection->EFF_GPR_Sec->controller2; + + lowerEID = AFSection->EFF_GPR_Sec->lowerEID; + + upperEID = AFSection->EFF_GPR_Sec->upperEID; + + entry = 0x00; + + if(CANAF_gext_cnt != 0) + { + buf = LPC_CANAF_RAM->mask[count-1]; +// EID_temp = buf & 0x0FFFFFFF; + if((ctrl1 != ctrl2) || (lowerEID > upperEID) || (buf > ((ctrl1 << 29)|(lowerEID << 0)))) + { + return CAN_AF_ENTRY_ERROR; + } + } + + entry = (ctrl1 << 29)|(lowerEID << 0); + + LPC_CANAF_RAM->mask[count++] = entry; + + entry = (ctrl2 << 29)|(upperEID << 0); + + LPC_CANAF_RAM->mask[count++] = entry; + + CANAF_gext_cnt++; + + AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry)); + } + } + + //update address values + LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2; + + LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2); + + LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2); + + LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2); + + LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3); + + if(FULLCAN_ENABLE == DISABLE) + { + LPC_CANAF->AFMR = 0x00; // Normal mode + } + else + { + LPC_CANAF->AFMR = 0x04; + } + + return CAN_OK; +} +/********************************************************************//** + * @brief Add Explicit ID into AF Look-Up Table dynamically. + * @param[in] canId The Id of the expected CAN component + * + * @param[in] id: The ID of entry will be added + * @param[in] format: is the type of ID Frame Format, should be: + * - STD_ID_FORMAT: 11-bit ID value + * - EXT_ID_FORMAT: 29-bit ID value + * @return CAN Error, could be: + * - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available + * - CAN_ID_EXIT_ERROR: ID exited in table + * - CAN_OK: ID is added into table successfully + *********************************************************************/ +CAN_ERROR CAN_LoadExplicitEntry(uint8_t canId, uint32_t id, CAN_ID_FORMAT_Type format) +{ + uint32_t buf0 = 0, buf1 = 0; + int16_t cnt1 = 0, cnt2 = 0, bound1 = 0, total = 0; + + /* Acceptance Filter Memory full - return */ + total =((CANAF_FullCAN_cnt + 1) >> 1) + CANAF_FullCAN_cnt * 3 + ((CANAF_std_cnt + 1) >> 1) \ + + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1); + + if (total >= 512) + { + //don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + + /*********** Add Explicit Standard Identifier Frame Format entry *********/ + if(format == STD_ID_FORMAT) + { + id &= 0x07FF; + + id |= canId << 13;/* Add controller number */ + + /* Move all remaining sections one place up + if new entry will increase FullCAN list */ + if ((CANAF_std_cnt & 0x0001) == 0) + { + cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); + + bound1 = total - cnt1; + + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + while(bound1--) + { + cnt1++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = buf0; + + buf0 = buf1; + } + } + + if (CANAF_std_cnt == 0) + { + cnt2 = (CANAF_FullCAN_cnt + 1)>>1; + + /* For entering first ID */ + LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16); + } + else if (CANAF_std_cnt == 1) + { + cnt2 = (CANAF_FullCAN_cnt + 1) >> 1; + + /* For entering second ID */ + if (((LPC_CANAF_RAM->mask[cnt2] >> 16)& 0xE7FF) > id) + { + LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16); + } + else + { + LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id; + } + } + else + { + /* Find where to insert new ID */ + cnt1 = (CANAF_FullCAN_cnt+1)>>1; + + cnt2 = CANAF_std_cnt; + + bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); + + while (cnt1 < bound1) + { + /* Loop through standard existing IDs */ + if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id) + { + cnt2 = cnt1 * 2; + break; + } + + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id) + { + cnt2 = cnt1 * 2 + 1; + break; + } + + cnt1++; + } + + /* cnt1 = U32 where to insert new ID */ + /* cnt2 = U16 where to insert new ID */ + + if (cnt1 == bound1) + { + /* Adding ID as last entry */ + /* Even number of IDs exists */ + if ((CANAF_std_cnt & 0x0001) == 0) + { + LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); + } + /* Odd number of IDs exists */ + else + { + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; + } + } + else + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + + if ((cnt2 & 0x0001) == 0) + { + /* Insert new mask to even address*/ + buf1 = (id << 16) | (buf0 >> 16); + } + else + { + /* Insert new mask to odd address */ + buf1 = (buf0 & 0xFFFF0000) | id; + } + + LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ + + bound1 = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt+1) >> 1) - 1; + + /* Move all remaining standard mask entries one place up */ + while (cnt1 < bound1) + { + cnt1++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); + + buf0 = buf1; + } + + if ((CANAF_std_cnt & 0x0001) == 0) + { + /* Even number of IDs exists */ + LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF); + } + } + } + + CANAF_std_cnt++; + + //update address values + LPC_CANAF->SFF_GRP_sa += 0x04 ; + + LPC_CANAF->EFF_sa += 0x04 ; + + LPC_CANAF->EFF_GRP_sa += 0x04; + + LPC_CANAF->ENDofTable += 0x04; + } + + /*********** Add Explicit Extended Identifier Frame Format entry *********/ + else + { + /* Add controller number */ + id |= canId << 29; + + cnt1 = ((CANAF_FullCAN_cnt+1) >> 1) + (((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt); + + cnt2 = 0; + + while (cnt2 < CANAF_ext_cnt) + { + /* Loop through extended existing masks*/ + if (LPC_CANAF_RAM->mask[cnt1] > id) + { + break; + } + + cnt1++;/* cnt1 = U32 where to insert new mask */ + + cnt2++; + } + + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + + LPC_CANAF_RAM->mask[cnt1] = id; /* Insert mask */ + + CANAF_ext_cnt++; + + bound1 = total; + + /* Move all remaining extended mask entries one place up*/ + while (cnt2 < bound1) + { + cnt1++; + + cnt2++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = buf0; + + buf0 = buf1; + } + + /* update address values */ + LPC_CANAF->EFF_GRP_sa += 4; + + LPC_CANAF->ENDofTable += 4; + } + + if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode + { + LPC_CANAF->AFMR = 0x00;//not use FullCAN mode + } + else + { + LPC_CANAF->AFMR = 0x04; + } + + return CAN_OK; +} + +/********************************************************************//** + * @brief Load FullCAN entry into AFLUT + * @param[in] canId The Id of the expected CAN component + * + * @param[in] id: identifier of entry that will be added + * @return CAN_ERROR, could be: + * - CAN_OK: loading is successful + * - CAN_ID_EXIT_ERROR: ID exited in FullCAN Section + * - CAN_OBJECTS_FULL_ERROR: no more space available + *********************************************************************/ +CAN_ERROR CAN_LoadFullCANEntry (uint8_t canId, uint16_t id) +{ + uint32_t buf0 = 0, buf1 = 0, buf2 = 0; + uint32_t tmp0 = 0, tmp1 = 0, tmp2 = 0; + int16_t cnt1 = 0, cnt2 = 0, bound1 = 0, total = 0; + + /* Acceptance Filter Memory full - return */ + total =((CANAF_FullCAN_cnt + 1) >> 1) + CANAF_FullCAN_cnt*3 + ((CANAF_std_cnt + 1) >> 1) \ + + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1); + + //don't have enough space for this fullCAN Entry and its Object(3*32 bytes) + if ((total >= 508) || (CANAF_FullCAN_cnt >= 64)) + { + return CAN_OBJECTS_FULL_ERROR; + } + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + + /* Add mask for standard identifiers */ + id &= 0x07FF; + + id |= (canId << 13) | (1 << 11); + + /* Move all remaining sections one place up + if new entry will increase FullCAN list */ + if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0)) + { + //then remove remaining section + cnt1 = (CANAF_FullCAN_cnt >> 1); + + bound1 = total; + + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + while (bound1--) + { + cnt1++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = buf0; + + buf0 = buf1; + } + } + if (CANAF_FullCAN_cnt == 0) + { + /* For entering first ID */ + LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16); + } + else if (CANAF_FullCAN_cnt == 1) + { + /* For entering second ID */ + if (((LPC_CANAF_RAM->mask[0] >> 16)& 0xE7FF) > id) + { + LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16); + } + else + { + LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id; + } + } + else + { + /* Find where to insert new ID */ + cnt1 = 0; + + cnt2 = CANAF_FullCAN_cnt; + + bound1 = (CANAF_FullCAN_cnt - 1) >> 1; + + while (cnt1 <= bound1) + { + /* Loop through standard existing IDs */ + if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > (id & 0xE7FF)) + { + cnt2 = cnt1 * 2; + break; + } + + + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > (id & 0xE7FF)) + { + cnt2 = cnt1 * 2 + 1; + break; + } + + cnt1++; + } + /* cnt1 = U32 where to insert new ID */ + /* cnt2 = U16 where to insert new ID */ + + if (cnt1 > bound1) + { + /* Adding ID as last entry */ + /* Even number of IDs exists */ + if ((CANAF_FullCAN_cnt & 0x0001) == 0) + { + LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); + } + /* Odd number of IDs exists */ + else + { + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; + } + } + else + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + + if ((cnt2 & 0x0001) == 0) + { + /* Insert new mask to even address*/ + buf1 = (id << 16) | (buf0 >> 16); + } + else + { + /* Insert new mask to odd address */ + buf1 = (buf0 & 0xFFFF0000) | id; + } + + LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ + + bound1 = CANAF_FullCAN_cnt >> 1; + + /* Move all remaining standard mask entries one place up */ + while (cnt1 < bound1) + { + cnt1++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); + + buf0 = buf1; + } + + if ((CANAF_FullCAN_cnt & 0x0001) == 0) + { + /* Even number of IDs exists */ + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) + | (0x0000FFFF); + } + } + } + + //restruct FulCAN Object Section + bound1 = CANAF_FullCAN_cnt - cnt2; + + cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1; + + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + + buf2 = LPC_CANAF_RAM->mask[cnt1+2]; + + LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00; + + cnt1+=3; + + while(bound1--) + { + tmp0 = LPC_CANAF_RAM->mask[cnt1]; + + tmp1 = LPC_CANAF_RAM->mask[cnt1+1]; + + tmp2 = LPC_CANAF_RAM->mask[cnt1+2]; + + LPC_CANAF_RAM->mask[cnt1]= buf0; + + LPC_CANAF_RAM->mask[cnt1+1]= buf1; + + LPC_CANAF_RAM->mask[cnt1+2]= buf2; + + buf0 = tmp0; + + buf1 = tmp1; + + buf2 = tmp2; + + cnt1+=3; + } + + CANAF_FullCAN_cnt++; + + //update address values + LPC_CANAF->SFF_sa += 0x04; + + LPC_CANAF->SFF_GRP_sa += 0x04 ; + + LPC_CANAF->EFF_sa += 0x04 ; + + LPC_CANAF->EFF_GRP_sa += 0x04; + + LPC_CANAF->ENDofTable += 0x04; + + LPC_CANAF->AFMR = 0x04; + + return CAN_OK; +} + +/********************************************************************//** + * @brief Load Group entry into AFLUT + * @param[in] canId The Id of the expected CAN component + * + * @param[in] lowerID, upperID: lower and upper identifier of entry + * @param[in] format: type of ID format, should be: + * - STD_ID_FORMAT: Standard ID format (11-bit value) + * - EXT_ID_FORMAT: Extended ID format (29-bit value) + * @return CAN_ERROR, could be: + * - CAN_OK: loading is successful + * - CAN_CONFLICT_ID_ERROR: Conflict ID occurs + * - CAN_OBJECTS_FULL_ERROR: no more space available + *********************************************************************/ +CAN_ERROR CAN_LoadGroupEntry(uint8_t canId, uint32_t lowerID, + uint32_t upperID, CAN_ID_FORMAT_Type format) +{ + uint32_t buf0, buf1, entry1, entry2, LID,UID; + int16_t cnt1, bound1, total; + + if(lowerID > upperID) + return CAN_CONFLICT_ID_ERROR; + + total =((CANAF_FullCAN_cnt+1) >> 1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1) \ + + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + + /*********Add Group of Standard Identifier Frame Format************/ + if(format == STD_ID_FORMAT) + { + if ((total >= 512)) + { + //don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + + lowerID &=0x7FF; //mask ID + + upperID &=0x7FF; + + entry1 = (canId << 29) | (lowerID << 16) | (canId << 13)|(upperID << 0); + + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1); + + //if this is the first Group standard ID entry + if(CANAF_gstd_cnt == 0) + { + LPC_CANAF_RAM->mask[cnt1] = entry1; + } + else + { + //find the position to add new Group entry + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt; + + while(cnt1 < bound1) + { + //compare controller first + while((LPC_CANAF_RAM->mask[cnt1] >> 29)< (entry1 >> 29))//increase until meet greater or equal controller + cnt1++; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + if((LPC_CANAF_RAM->mask[cnt1] >> 29)> (entry1 >> 29)) //meet greater controller + { + //add at this position + LPC_CANAF_RAM->mask[cnt1] = entry1; + break; + } + else //meet equal controller + { + LID = (buf0 >> 16)&0x7FF; + UID = buf0 & 0x7FF; + if (upperID <= LID) + { + //add new entry before this entry + LPC_CANAF_RAM->mask[cnt1] = entry1; + break; + } + else if (lowerID >= UID) + { + //load next entry to compare + cnt1 ++; + } + else + return CAN_CONFLICT_ID_ERROR; + } + } + if(cnt1 >= bound1) + { + //add new entry at the last position in this list + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = entry1; + } + + //remove all remaining entry of this section one place up + bound1 = total - cnt1; + + while(bound1--) + { + cnt1++; + + buf1 = LPC_CANAF_RAM->mask[cnt1]; + + LPC_CANAF_RAM->mask[cnt1] = buf0; + + buf0 = buf1; + } + } + + CANAF_gstd_cnt++; + + //update address values + LPC_CANAF->EFF_sa +=0x04 ; + + LPC_CANAF->EFF_GRP_sa +=0x04; + + LPC_CANAF->ENDofTable +=0x04; + } + + + /*********Add Group of Extended Identifier Frame Format************/ + else + { + if ((total >= 511)) + { + //don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + + lowerID &= 0x1FFFFFFF; //mask ID + + upperID &= 0x1FFFFFFF; + + entry1 = (canId << 29)|(lowerID << 0); + + entry2 = (canId << 29)|(upperID << 0); + + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt; + + //if this is the first Group standard ID entry + if(CANAF_gext_cnt == 0) + { + LPC_CANAF_RAM->mask[cnt1] = entry1; + + LPC_CANAF_RAM->mask[cnt1+1] = entry2; + } + else + { + //find the position to add new Group entry + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \ + + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + + while(cnt1 < bound1) + { + while((LPC_CANAF_RAM->mask[cnt1] >>29)< canId) //increase until meet greater or equal controller + cnt1++; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + if((LPC_CANAF_RAM->mask[cnt1] >> 29)> canId) //meet greater controller + { + //add at this position + LPC_CANAF_RAM->mask[cnt1] = entry1; + LPC_CANAF_RAM->mask[++cnt1] = entry2; + break; + } + else //meet equal controller + { + LID = buf0 & 0x1FFFFFFF; //mask ID + UID = buf1 & 0x1FFFFFFF; + if (upperID <= LID) + { + //add new entry before this entry + LPC_CANAF_RAM->mask[cnt1] = entry1; + LPC_CANAF_RAM->mask[++cnt1] = entry2; + break; + } + else if (lowerID >= UID) + { + //load next entry to compare + cnt1 +=2; + } + else + return CAN_CONFLICT_ID_ERROR; + } + } + if(cnt1 >= bound1) + { + //add new entry at the last position in this list + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + + LPC_CANAF_RAM->mask[cnt1] = entry1; + + LPC_CANAF_RAM->mask[++cnt1] = entry2; + } + + //remove all remaining entry of this section two place up + bound1 = total - cnt1 + 1; + + cnt1++; + + while(bound1>0) + { + entry1 = LPC_CANAF_RAM->mask[cnt1]; + + entry2 = LPC_CANAF_RAM->mask[cnt1+1]; + + LPC_CANAF_RAM->mask[cnt1] = buf0; + + LPC_CANAF_RAM->mask[cnt1+1] = buf1; + + buf0 = entry1; + + buf1 = entry2; + + cnt1 +=2; + + bound1 -=2; + } + } + + CANAF_gext_cnt++; + + //update address values + LPC_CANAF->ENDofTable +=0x08; + } + + LPC_CANAF->AFMR = 0x04; + + return CAN_OK; +} + +/********************************************************************//** + * @brief Remove AFLUT entry (FullCAN entry and Explicit Standard entry) + * @param[in] EntryType: the type of entry that want to remove, should be: + * - FULLCAN_ENTRY + * - EXPLICIT_STANDARD_ENTRY + * - GROUP_STANDARD_ENTRY + * - EXPLICIT_EXTEND_ENTRY + * - GROUP_EXTEND_ENTRY + * @param[in] position: the position of this entry in its section + * Note: the first position is 0 + * @return CAN_ERROR, could be: + * - CAN_OK: removing is successful + * - CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit + *********************************************************************/ +CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position) +{ + uint16_t cnt, bound, total; + uint32_t buf0, buf1; + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + + total = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1) + \ + + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1); + + + /************** Remove FullCAN Entry *************/ + if(EntryType == FULLCAN_ENTRY) + { + if((CANAF_FullCAN_cnt == 0)||(position >= CANAF_FullCAN_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = position >> 1; + + buf0 = LPC_CANAF_RAM->mask[cnt]; + + bound = (CANAF_FullCAN_cnt - position -1)>>1; + + if((position & 0x0001) == 0) //event position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + + LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); + + buf0 = buf1; + + cnt++; + } + } + else //odd position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + + LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16); + + LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16; + + buf0 = buf1<<16; + + cnt++; + } + } + if((CANAF_FullCAN_cnt & 0x0001) == 0) + { + if((position & 0x0001)==0) + LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); + else + LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; + } + else + { + //remove all remaining section one place down + cnt = (CANAF_FullCAN_cnt + 1)>>1; + + bound = total + CANAF_FullCAN_cnt * 3; + + while(bound>cnt) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + + LPC_CANAF_RAM->mask[cnt-1]=0x00; + + //update address values + LPC_CANAF->SFF_sa -= 0x04; + + LPC_CANAF->SFF_GRP_sa -= 0x04 ; + + LPC_CANAF->EFF_sa -= 0x04 ; + + LPC_CANAF->EFF_GRP_sa -= 0x04; + + LPC_CANAF->ENDofTable -= 0x04; + } + + CANAF_FullCAN_cnt--; + + //delete its FullCAN Object in the FullCAN Object section + //remove all remaining FullCAN Object three place down + cnt = total + position * 3; + + bound = (CANAF_FullCAN_cnt - position + 1) * 3; + + while(bound) + { + LPC_CANAF_RAM->mask[cnt]= LPC_CANAF_RAM->mask[cnt+3];; + + LPC_CANAF_RAM->mask[cnt+1]= LPC_CANAF_RAM->mask[cnt+4]; + + LPC_CANAF_RAM->mask[cnt+2]= LPC_CANAF_RAM->mask[cnt+5]; + + bound -= 3; + + cnt += 3; + } + } + } + + /************** Remove Explicit Standard ID Entry *************/ + else if(EntryType == EXPLICIT_STANDARD_ENTRY) + { + if((CANAF_std_cnt == 0)||(position >= CANAF_std_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt+1) >> 1) + (position >> 1); + + buf0 = LPC_CANAF_RAM->mask[cnt]; + + bound = (CANAF_std_cnt - position - 1) >> 1; + + if((position & 0x0001) == 0) //event position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt + 1]; + + LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); + + buf0 = buf1; + + cnt++; + } + } + else //odd position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt + 1]; + + LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000) | (buf1 >> 16); + + LPC_CANAF_RAM->mask[cnt + 1] = LPC_CANAF_RAM->mask[cnt + 1] << 16; + + buf0 = buf1<<16; + + cnt++; + } + } + if((CANAF_std_cnt & 0x0001) == 0) + { + if((position & 0x0001)==0) + LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); + else + LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; + } + else + { + //remove all remaining section one place down + cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1); + + bound = total + CANAF_FullCAN_cnt * 3; + + while(bound>cnt) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + + LPC_CANAF_RAM->mask[cnt-1]=0x00; + + //update address value + LPC_CANAF->SFF_GRP_sa -= 0x04 ; + + LPC_CANAF->EFF_sa -= 0x04 ; + + LPC_CANAF->EFF_GRP_sa -= 0x04; + + LPC_CANAF->ENDofTable -= 0x04; + } + + CANAF_std_cnt--; + } + } + + /************** Remove Group of Standard ID Entry *************/ + else if(EntryType == GROUP_STANDARD_ENTRY) + { + if((CANAF_gstd_cnt == 0)||(position >= CANAF_gstd_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1; + + bound = total + CANAF_FullCAN_cnt * 3; + + while (cnt < bound) + { + LPC_CANAF_RAM->mask[cnt - 1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt - 1]=0x00; + } + + CANAF_gstd_cnt--; + + //update address value + LPC_CANAF->EFF_sa -= 0x04; + + LPC_CANAF->EFF_GRP_sa -= 0x04; + + LPC_CANAF->ENDofTable -= 0x04; + } + + /************** Remove Explicit Extended ID Entry *************/ + else if(EntryType == EXPLICIT_EXTEND_ENTRY) + { + if((CANAF_ext_cnt == 0)||(position >= CANAF_ext_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1; + + bound = total + CANAF_FullCAN_cnt * 3; + + while (cntmask[cnt - 1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt - 1]=0x00; + } + + CANAF_ext_cnt--; + + LPC_CANAF->EFF_GRP_sa -= 0x04; + + LPC_CANAF->ENDofTable -= 0x04; + } + + /************** Remove Group of Extended ID Entry *************/ + else + { + if((CANAF_gext_cnt == 0)||(position >= CANAF_gext_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = total - (CANAF_gext_cnt << 1) + (position << 1); + + bound = total + CANAF_FullCAN_cnt * 3; + + while (cntmask[cnt] = LPC_CANAF_RAM->mask[cnt + 2]; + + LPC_CANAF_RAM->mask[cnt + 1] = LPC_CANAF_RAM->mask[cnt + 3]; + + cnt += 2; + } + } + + CANAF_gext_cnt--; + + LPC_CANAF->ENDofTable -= 0x08; + } + + LPC_CANAF->AFMR = 0x04; + + return CAN_OK; +} + +/********************************************************************//** + * @brief Send message data + * @param[in] canId The Id of the expected CAN component + * + * @param[in] CAN_Msg point to the CAN_MSG_Type Structure, it contains message + * information such as: ID, DLC, RTR, ID Format + * @return Status: + * - SUCCESS: send message successfully + * - ERROR: send message unsuccessfully + *********************************************************************/ +Status CAN_SendMsg (uint8_t canId, CAN_MSG_Type *CAN_Msg) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + uint32_t data; + + //Check status of Transmit Buffer 1 + if (pCan->SR & (1 << 2)) + { + /* Transmit Channel 1 is available */ + /* Write frame informations and frame data into its CANxTFI1, + * CANxTID1, CANxTDA1, CANxTDB1 register */ + pCan->TFI1 &= ~ 0x000F0000; + + pCan->TFI1 |= (CAN_Msg->len) << 16; + + if(CAN_Msg->type == REMOTE_FRAME) + { + pCan->TFI1 |= (1 << 30); //set bit RTR + } + else + { + pCan->TFI1 &= ~(1 << 30); + } + + if(CAN_Msg->format == EXT_ID_FORMAT) + { + pCan->TFI1 |= (((uint32_t)1) << 31); //set bit FF + } + else + { + pCan->TFI1 &= ~(((uint32_t)1) << 31); + } + + /* Write CAN ID*/ + pCan->TID1 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1]))<< 8) | ((CAN_Msg->dataA[2]) << 16) | ((CAN_Msg->dataA[3]) << 24); + + pCan->TDA1 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8)|((CAN_Msg->dataB[2]) << 16)|((CAN_Msg->dataB[3]) << 24); + + pCan->TDB1 = data; + + /*Write transmission request*/ + pCan->CMR = 0x21; + + return SUCCESS; + } + + //check status of Transmit Buffer 2 + else if((pCan->SR) & (1 << 10)) + { + /* Transmit Channel 2 is available */ + /* Write frame informations and frame data into its CANxTFI2, + * CANxTID2, CANxTDA2, CANxTDB2 register */ + pCan->TFI2 &= ~0x000F0000; + + pCan->TFI2 |= (CAN_Msg->len) << 16; + + if(CAN_Msg->type == REMOTE_FRAME) + { + pCan->TFI2 |= (1 << 30); //set bit RTR + } + else + { + pCan->TFI2 &= ~(1 << 30); + } + + if(CAN_Msg->format == EXT_ID_FORMAT) + { + pCan->TFI2 |= (((uint32_t)1) << 31); //set bit FF + } + else + { + pCan->TFI2 &= ~(((uint32_t)1) << 31); + } + + /* Write CAN ID*/ + pCan->TID2 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1])) << 8) | ((CAN_Msg->dataA[2]) << 16)|((CAN_Msg->dataA[3]) << 24); + + pCan->TDA2 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8) | ((CAN_Msg->dataB[2]) << 16) | ((CAN_Msg->dataB[3]) << 24); + + pCan->TDB2 = data; + + /*Write transmission request*/ + pCan->CMR = 0x41; + + return SUCCESS; + } + + //check status of Transmit Buffer 3 + else if (pCan->SR & (1<<18)) + { + /* Transmit Channel 3 is available */ + /* Write frame informations and frame data into its CANxTFI3, + * CANxTID3, CANxTDA3, CANxTDB3 register */ + pCan->TFI3 &= ~0x000F0000; + + pCan->TFI3 |= (CAN_Msg->len) << 16; + + if(CAN_Msg->type == REMOTE_FRAME) + { + pCan->TFI3 |= (1 << 30); //set bit RTR + } + else + { + pCan->TFI3 &= ~(1 << 30); + } + + if(CAN_Msg->format == EXT_ID_FORMAT) + { + pCan->TFI3 |= (((uint32_t)1) << 31); //set bit FF + } + else + { + pCan->TFI3 &= ~(((uint32_t)1) << 31); + } + + /* Write CAN ID*/ + pCan->TID3 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1])) << 8) | ((CAN_Msg->dataA[2]) << 16) | ((CAN_Msg->dataA[3]) << 24); + + pCan->TDA3 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8) | ((CAN_Msg->dataB[2]) << 16) | ((CAN_Msg->dataB[3]) << 24); + + pCan->TDB3 = data; + + /*Write transmission request*/ + pCan->CMR = 0x81; + + return SUCCESS; + } + else + { + return ERROR; + } +} + +/********************************************************************//** + * @brief Receive message data + * @param[in] canId The Id of the expected CAN component + * + * @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received + * message information such as: ID, DLC, RTR, ID Format + * @return Status: + * - SUCCESS: receive message successfully + * - ERROR: receive message unsuccessfully + *********************************************************************/ +Status CAN_ReceiveMsg (uint8_t canId, CAN_MSG_Type *CAN_Msg) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + uint32_t data; + + //check status of Receive Buffer + if((pCan->SR &0x00000001)) + { + /* Receive message is available */ + /* Read frame informations */ + CAN_Msg->format = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31); + + CAN_Msg->type = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30); + + CAN_Msg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16); + + /* Read CAN message identifier */ + CAN_Msg->id = pCan->RID; + + /* Read the data if received message was DATA FRAME */ + if (CAN_Msg->type == DATA_FRAME) + { + /* Read first 4 data bytes */ + data = pCan->RDA; + + *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; + + *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00) >> 8;; + + *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000) >> 16; + + *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000) >> 24; + + /* Read second 4 data bytes */ + data = pCan->RDB; + + *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; + + *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00) >> 8; + + *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000) >> 16; + + *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000) >> 24; + + /*release receive buffer*/ + pCan->CMR = 0x04; + } + else + { + /* Received Frame is a Remote Frame, not have data, we just receive + * message information only */ + pCan->CMR = 0x04; /*release receive buffer*/ + + return SUCCESS; + } + } + else + { + // no receive message available + return ERROR; + } + + return SUCCESS; +} + +/********************************************************************//** + * @brief Receive FullCAN Object + * @param[in] CANAFx: CAN Acceptance Filter register, should be: LPC_CANAF + * @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received + * message information such as: ID, DLC, RTR, ID Format + * @return CAN_ERROR, could be: + * - CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received + * - CAN_OK: Received FullCAN Object successful + * + *********************************************************************/ +CAN_ERROR FCAN_ReadObj (CAN_MSG_Type *CAN_Msg) +{ + uint32_t *pSrc, data; + uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx; + + interrut_word = 0; + + if (LPC_CANAF->FCANIC0 != 0) + { + interrut_word = LPC_CANAF->FCANIC0; + + head_idx = 0; + + tail_idx = 31; + } + else if (LPC_CANAF->FCANIC1 != 0) + { + interrut_word = LPC_CANAF->FCANIC1; + + head_idx = 32; + + tail_idx = 63; + } + + if (interrut_word != 0) + { + /* Detect for interrupt pending */ + msg_idx = 0; + + for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++) + { + test_bit = interrut_word & 0x1; + + interrut_word = interrut_word >> 1; + + if (test_bit) + { + pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12); + + /* Has been finished updating the content */ + if ((*pSrc & 0x03000000L) == 0x03000000L) + { + /*clear semaphore*/ + *pSrc &= 0xFCFFFFFF; + + /*Set to DatA*/ + pSrc++; + + /* Copy to dest buf */ + data = *pSrc; + + *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; + + *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00) >> 8; + + *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000) >> 16; + + *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000) >> 24; + + /*Set to DatB*/ + pSrc++; + + /* Copy to dest buf */ + data = *pSrc; + + *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; + + *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00) >> 8; + + *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000) >> 16; + + *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000) >> 24; + + /*Back to Dat1*/ + pSrc -= 2; + + CAN_Msg->id = *pSrc & 0x7FF; + + CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F; + + CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value + + CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01; + + /*Re-read semaphore*/ + if ((*pSrc & 0x03000000L) == 0) + { + return CAN_OK; + } + } + } + } + } + + return CAN_FULL_OBJ_NOT_RCV; +} + +/********************************************************************//** + * @brief Get CAN Control Status + * @param[in] canId The Id of the expected CAN component + * + * @param[in] arg: type of CAN status to get from CAN status register + * Should be: + * - CANCTRL_GLOBAL_STS: CAN Global Status + * - CANCTRL_INT_CAP: CAN Interrupt and Capture + * - CANCTRL_ERR_WRN: CAN Error Warning Limit + * - CANCTRL_STS: CAN Control Status + * @return Current Control Status that you want to get value + *********************************************************************/ +uint32_t CAN_GetCTRLStatus (uint8_t canId, CAN_CTRL_STS_Type arg) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + switch (arg) + { + case CANCTRL_GLOBAL_STS: + return pCan->GSR; + + case CANCTRL_INT_CAP: + return pCan->ICR; + + case CANCTRL_ERR_WRN: + return pCan->EWL; + + default: // CANCTRL_STS + return pCan->SR; + } +} +/********************************************************************//** + * @brief Get CAN Central Status + * @param[in] CANCRx point to LPC_CANCR_TypeDef, should be: LPC_CANCR + * @param[in] arg: type of CAN status to get from CAN Central status register + * Should be: + * - CANCR_TX_STS: Central CAN Tx Status + * - CANCR_RX_STS: Central CAN Rx Status + * - CANCR_MS: Central CAN Miscellaneous Status + * @return Current Central Status that you want to get value + *********************************************************************/ +uint32_t CAN_GetCRStatus (CAN_CR_STS_Type arg) +{ + switch (arg) + { + case CANCR_TX_STS: + return LPC_CANCR->TxSR; + + case CANCR_RX_STS: + return LPC_CANCR->RxSR; + + default: // CANCR_MS + return LPC_CANCR->MSR; + } +} +/********************************************************************//** + * @brief Enable/Disable CAN Interrupt + * @param[in] canId The Id of the expected CAN component + * + * @param[in] arg: type of CAN interrupt that you want to enable/disable + * Should be: + * - CANINT_RIE: CAN Receiver Interrupt Enable + * - CANINT_TIE1: CAN Transmit Interrupt Enable + * - CANINT_EIE: CAN Error Warning Interrupt Enable + * - CANINT_DOIE: CAN Data Overrun Interrupt Enable + * - CANINT_WUIE: CAN Wake-Up Interrupt Enable + * - CANINT_EPIE: CAN Error Passive Interrupt Enable + * - CANINT_ALIE: CAN Arbitration Lost Interrupt Enable + * - CANINT_BEIE: CAN Bus Error Interrupt Enable + * - CANINT_IDIE: CAN ID Ready Interrupt Enable + * - CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2 + * - CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3 + * - CANINT_FCE: FullCAN Interrupt Enable + * @param[in] NewState: New state of this function, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void CAN_IRQCmd (uint8_t canId, CAN_INT_EN_Type arg, FunctionalState NewState) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + if(NewState == ENABLE) + { + if(arg == CANINT_FCE) + { + LPC_CANAF->AFMR = 0x01; + + LPC_CANAF->FCANIE = 0x01; + + LPC_CANAF->AFMR = 0x04; + } + else + pCan->IER |= (1 << arg); + } + else + { + if(arg == CANINT_FCE) + { + LPC_CANAF->AFMR = 0x01; + + LPC_CANAF->FCANIE = 0x01; + + LPC_CANAF->AFMR = 0x00; + } + else + pCan->IER &= ~(1 << arg); + } +} + +/********************************************************************//** + * @brief Setting Acceptance Filter mode + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @param[in] AFMode: type of AF mode that you want to set, should be: + * - CAN_NORMAL: Normal mode + * - CAN_ACC_OFF: Acceptance Filter Off Mode + * - CAN_ACC_BP: Acceptance Fileter Bypass Mode + * - CAN_EFCAN: FullCAN Mode Enhancement + * @return none + *********************************************************************/ +void CAN_SetAFMode (CAN_AFMODE_Type AFMode) +{ + switch(AFMode) + { + case CAN_NORMAL: + LPC_CANAF->AFMR = 0x00; + break; + + case CAN_ACC_OFF: + LPC_CANAF->AFMR = 0x01; + break; + + case CAN_ACC_BP: + LPC_CANAF->AFMR = 0x02; + break; + + case CAN_EFCAN: + LPC_CANAF->AFMR = 0x04; + break; + } +} + +/********************************************************************//** + * @brief Enable/Disable CAN Mode + * @param[in] canId The Id of the expected CAN component + * + * @param[in] mode: type of CAN mode that you want to enable/disable, should be: + * - CAN_OPERATING_MODE: Normal Operating Mode + * - CAN_RESET_MODE: Reset Mode + * - CAN_LISTENONLY_MODE: Listen Only Mode + * - CAN_SELFTEST_MODE: Self Test Mode + * - CAN_TXPRIORITY_MODE: Transmit Priority Mode + * - CAN_SLEEP_MODE: Sleep Mode + * - CAN_RXPOLARITY_MODE: Receive Polarity Mode + * - CAN_TEST_MODE: Test Mode + * @param[in] NewState: New State of this function, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void CAN_ModeConfig(uint8_t canId, CAN_MODE_Type mode, FunctionalState NewState) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + switch(mode) + { + case CAN_OPERATING_MODE: + pCan->MOD = 0x00; + break; + + case CAN_RESET_MODE: + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_RM; + else + pCan->MOD &= ~CAN_MOD_RM; + + break; + + case CAN_LISTENONLY_MODE: + pCan->MOD |=CAN_MOD_RM;//Enter Reset mode + + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_LOM; + else + pCan->MOD &= ~ CAN_MOD_LOM; + + pCan->MOD &= ~ CAN_MOD_RM;//Release Reset mode + + break; + + case CAN_SELFTEST_MODE: + pCan->MOD |= CAN_MOD_RM;//Enter Reset mode + + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_STM; + else + pCan->MOD &= ~ CAN_MOD_STM; + + pCan->MOD &= ~ CAN_MOD_RM;//Release Reset mode + + break; + + case CAN_TXPRIORITY_MODE: + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_TPM; + else + pCan->MOD &= ~ CAN_MOD_TPM; + + break; + + case CAN_SLEEP_MODE: + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_SM; + else + pCan->MOD &= ~ CAN_MOD_SM; + + break; + + case CAN_RXPOLARITY_MODE: + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_RPM; + else + pCan->MOD &= ~ CAN_MOD_RPM; + + break; + + case CAN_TEST_MODE: + if(NewState == ENABLE) + pCan->MOD |= CAN_MOD_TM; + else + pCan->MOD &= ~ CAN_MOD_TM; + + break; + } +} +/*********************************************************************//** + * @brief Set CAN command request + * @param[in] canId The Id of the expected CAN component + * + * @param[in] CMRType command request type, should be: + * - CAN_CMR_TR: Transmission request + * - CAN_CMR_AT: Abort Transmission request + * - CAN_CMR_RRB: Release Receive Buffer request + * - CAN_CMR_CDO: Clear Data Overrun request + * - CAN_CMR_SRR: Self Reception request + * - CAN_CMR_STB1: Select Tx Buffer 1 request + * - CAN_CMR_STB2: Select Tx Buffer 2 request + * - CAN_CMR_STB3: Select Tx Buffer 3 request + * @return CANICR (CAN interrupt and Capture register) value + **********************************************************************/ +void CAN_SetCommand(uint8_t canId, uint32_t CMRType) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + pCan->CMR |= CMRType; +} + +/*********************************************************************//** + * @brief Get CAN interrupt status + * @param[in] canId The Id of the expected CAN component + * + * @return CANICR (CAN interrupt and Capture register) value + **********************************************************************/ +uint32_t CAN_IntGetStatus(uint8_t canId) +{ + LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId); + + return pCan->ICR; +} + +/*********************************************************************//** + * @brief Check if FullCAN interrupt enable or not + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @return IntStatus, could be: + * - SET: if FullCAN interrupt is enable + * - RESET: if FullCAN interrupt is disable + **********************************************************************/ +IntStatus CAN_FullCANIntGetStatus (void) +{ + if (LPC_CANAF->FCANIE) + return SET; + + return RESET; +} + +/*********************************************************************//** + * @brief Get value of FullCAN interrupt and capture register + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @param[in] type: FullCAN IC type, should be: + * - FULLCAN_IC0: FullCAN Interrupt Capture 0 + * - FULLCAN_IC1: FullCAN Interrupt Capture 1 + * @return FCANIC0 or FCANIC1 (FullCAN interrupt and Capture register) value + **********************************************************************/ +uint32_t CAN_FullCANPendGetStatus(FullCAN_IC_Type type) +{ + if (type == FULLCAN_IC0) + return LPC_CANAF->FCANIC0; + + return LPC_CANAF->FCANIC1; +} +/* End of Public Variables ---------------------------------------------------------- */ +/** + * @} + */ +#endif /*_CAN*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_clkpwr.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_clkpwr.c new file mode 100644 index 0000000000000000000000000000000000000000..fc4168763748b2d9d6177abe90409836db01c6b9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_clkpwr.c @@ -0,0 +1,326 @@ +/********************************************************************** +* $Id$ lpc_clkpwr.c 2011-06-02 +*//** +* @file lpc_clkpwr.c +* @brief Contains all functions support for Clock and Power Control +* firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup CLKPWR + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _CLKPWR + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_clkpwr.h" + +uint32_t USBFrequency = 0; + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup CLKPWR_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Set value of each Peripheral Clock Selection + * @param[in] ClkType clock type that will be divided, should be: + * - CLKPWR_CLKTYPE_CPU : CPU clock + * - CLKPWR_CLKTYPE_PER : Peripheral clock + * - CLKPWR_CLKTYPE_EMC : EMC clock + * - CLKPWR_CLKTYPE_USB : USB clock + * @param[in] DivVal Value of divider. This value should be set as follows: + * - CPU clock: DivVal must be in range: 0..31 + * - Peripheral clock: DivVal must be in range: 0..31 + * - EMC clock: DivVal must be: + * + 0: The EMC uses the same clock as the CPU + * + 1: The EMC uses a clock at half the rate of the CPU + * - USB clock: DivVal must be: + * + 0: the divider is turned off, no clock will + * be provided to the USB subsystem + * + 4: PLL0 output is divided by 4. PLL0 output must be 192MHz + * + 6: PLL0 output is divided by 6. PLL0 output must be 288MHz + * @return none + * Note: Pls assign right DivVal, this function will not check if it is illegal. + **********************************************************************/ +void CLKPWR_SetCLKDiv (uint8_t ClkType, uint8_t DivVal) +{ + uint32_t tmp; + switch(ClkType) + { + case CLKPWR_CLKTYPE_CPU: + tmp = LPC_SC->CCLKSEL & ~(0x1F); + tmp |= DivVal & 0x1F; + LPC_SC->CCLKSEL = tmp; + SystemCoreClockUpdate(); //Update clock + break; + case CLKPWR_CLKTYPE_PER: + tmp = LPC_SC->PCLKSEL & ~(0x1F); + tmp |= DivVal & 0x1F; + LPC_SC->PCLKSEL = tmp; + SystemCoreClockUpdate(); //Update clock + break; + case CLKPWR_CLKTYPE_EMC: + tmp = LPC_SC->EMCCLKSEL & ~(0x01); + tmp |= DivVal & 0x01; + LPC_SC->EMCCLKSEL = tmp; + SystemCoreClockUpdate(); //Update clock + break; + case CLKPWR_CLKTYPE_USB: + tmp = LPC_SC->USBCLKSEL & ~(0x1F); + tmp |= DivVal & 0x1F; + LPC_SC->USBCLKSEL |= DivVal & 0x1F; + SystemCoreClockUpdate(); //Update clock + break; + default: + while(1);//Error Loop; + } +} + +/*********************************************************************//** + * @brief Get current clock value + * @param[in] ClkType clock type that will be divided, should be: + * - CLKPWR_CLKTYPE_CPU : CPU clock + * - CLKPWR_CLKTYPE_PER : Peripheral clock + * - CLKPWR_CLKTYPE_EMC : EMC clock + * - CLKPWR_CLKTYPE_USB : USB clock + **********************************************************************/ +uint32_t CLKPWR_GetCLK (uint8_t ClkType) +{ + switch(ClkType) + { + case CLKPWR_CLKTYPE_CPU: + return SystemCoreClock; + + case CLKPWR_CLKTYPE_PER: + return PeripheralClock; + + case CLKPWR_CLKTYPE_EMC: + return EMCClock; + + case CLKPWR_CLKTYPE_USB: + return USBClock; + + default: + while(1);//error loop + } +} + +/*********************************************************************//** + * @brief Configure power supply for each peripheral according to NewState + * @param[in] PPType Type of peripheral used to enable power, + * should be one of the following: + * - CLKPWR_PCONP_PCLCD : LCD + * - CLKPWR_PCONP_PCTIM0 : Timer 0 + * - CLKPWR_PCONP_PCTIM1 : Timer 1 + * - CLKPWR_PCONP_PCUART0 : UART 0 + * - CLKPWR_PCONP_PCUART1 : UART 1 + * - CLKPWR_PCONP_PCPWM0 : PWM 0 + * - CLKPWR_PCONP_PCPWM1 : PWM 1 + * - CLKPWR_PCONP_PCI2C0 : I2C 0 + * - CLKPWR_PCONP_PCUART4 : UART4 + * - CLKPWR_PCONP_PCLCD : LCD + * - CLKPWR_PCONP_PCTIM0 : Timer 0 + * - CLKPWR_PCONP_PCRTC : RTC + * - CLKPWR_PCONP_PCSSP1 : SSP 1 + * - CLKPWR_PCONP_PCEMC : EMC + * - CLKPWR_PCONP_PCADC : ADC + * - CLKPWR_PCONP_PCAN1 : CAN 1 + * - CLKPWR_PCONP_PCAN2 : CAN 2 + * - CLKPWR_PCONP_PCGPIO : GPIO + * - CLKPWR_PCONP_PCMC : MCPWM + * - CLKPWR_PCONP_PCQEI : QEI + * - CLKPWR_PCONP_PCI2C1 : I2C 1 + * - CLKPWR_PCONP_PCSSP2 : SSP 2 + * - CLKPWR_PCONP_PCSSP0 : SSP 0 + * - CLKPWR_PCONP_PCTIM2 : Timer 2 + * - CLKPWR_PCONP_PCTIM3 : Timer 3 + * - CLKPWR_PCONP_PCUART2 : UART 2 + * - CLKPWR_PCONP_PCUART3 : UART 3 + * - CLKPWR_PCONP_PCI2C2 : I2C 2 + * - CLKPWR_PCONP_PCI2S : I2S + * - CLKPWR_PCONP_PCSDC : SDC + * - CLKPWR_PCONP_PCGPDMA : GPDMA + * - CLKPWR_PCONP_PCENET : Ethernet + * - CLKPWR_PCONP_PCUSB : USB + * + * @param[in] NewState New state of Peripheral Power, should be: + * - ENABLE : Enable power for this peripheral + * - DISABLE : Disable power for this peripheral + * + * @return none + **********************************************************************/ +void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + LPC_SC->PCONP |= PPType; + } + else if (NewState == DISABLE) + { + LPC_SC->PCONP &= ~PPType; + } +} + +#if 0 +// nxp21346 +/*********************************************************************//** + * @brief Configure hardware reset for each peripheral according to NewState + * @param[in] PPType Type of peripheral used to enable power, + * should be one of the following: + * - CLKPWR_RSTCON0_LCD : LCD + * - CLKPWR_RSTCON0_TIM0 : Timer 0 + - CLKPWR_RSTCON0_TIM1 : Timer 1 + - CLKPWR_RSTCON0_UART0 : UART 0 + - CLKPWR_RSTCON0_UART1 : UART 1 + - CLKPWR_RSTCON0_PWM0 : PWM 0 + - CLKPWR_RSTCON0_PWM1 : PWM 1 + - CLKPWR_RSTCON0_I2C0 : I2C 0 + - CLKPWR_RSTCON0_UART4 : UART 4 + - CLKPWR_RSTCON0_RTC : RTC + - CLKPWR_RSTCON0_SSP1 : SSP 1 + - CLKPWR_RSTCON0_EMC : EMC + - CLKPWR_RSTCON0_ADC : ADC + - CLKPWR_RSTCON0_CAN1 : CAN 1 + - CLKPWR_RSTCON0_CAN2 : CAN 2 + - CLKPWR_RSTCON0_GPIO : GPIO + - CLKPWR_RSTCON0_MCPWM : MCPWM + - CLKPWR_RSTCON0_QEI : QEI + - CLKPWR_RSTCON0_I2C1 : I2C 1 + - CLKPWR_RSTCON0_SSP2 : SSP 2 + - CLKPWR_RSTCON0_SSP0 : SSP 0 + - CLKPWR_RSTCON0_TIM2 : Timer 2 + - CLKPWR_RSTCON0_TIM3 : Timer 3 + - CLKPWR_RSTCON0_UART2 : UART 2 + - CLKPWR_RSTCON0_UART3 : UART 3 + - CLKPWR_RSTCON0_I2C2 : I2C 2 + - CLKPWR_RSTCON0_I2S : I2S + - CLKPWR_RSTCON0_SDC : SDC + - CLKPWR_RSTCON0_GPDMA : GPDMA + - CLKPWR_RSTCON0_ENET : Ethernet + - CLKPWR_RSTCON0_USB : USB + * + * @param[in] NewState New state of Peripheral Power, should be: + * - ENABLE : Enable power for this peripheral + * - DISABLE : Disable power for this peripheral + * + * @return none + **********************************************************************/ +void CLKPWR_ConfigReset(uint8_t PType, FunctionalState NewState) +{ + if(PType < 32) + { + if(NewState == ENABLE) + LPC_SC->RSTCON0 |=(1<RSTCON0 &=~(1<RSTCON1 |= (1<<(PType - 31)); + else + LPC_SC->RSTCON1 &= ~(1<<(PType - 31)); + } +} +// nxp21346 +#endif + +/*********************************************************************//** + * @brief Enter Sleep mode with co-operated instruction by the Cortex-M3. + * @param[in] None + * @return None + **********************************************************************/ +void CLKPWR_Sleep(void) +{ + LPC_SC->PCON = 0x00; + /* Sleep Mode*/ + __WFI(); +} + + +/*********************************************************************//** + * @brief Enter Deep Sleep mode with co-operated instruction by the Cortex-M3. + * @param[in] None + * @return None + **********************************************************************/ +void CLKPWR_DeepSleep(void) +{ + /* Deep-Sleep Mode, set SLEEPDEEP bit */ + SCB->SCR = 0x4; + LPC_SC->PCON = 0x00; + /* Deep Sleep Mode*/ + __WFI(); +} + + +/*********************************************************************//** + * @brief Enter Power Down mode with co-operated instruction by the Cortex-M3. + * @param[in] None + * @return None + **********************************************************************/ +void CLKPWR_PowerDown(void) +{ + /* Deep-Sleep Mode, set SLEEPDEEP bit */ + SCB->SCR = 0x4; + LPC_SC->PCON = 0x01; + /* Power Down Mode*/ + __WFI(); +} + + +/*********************************************************************//** + * @brief Enter Deep Power Down mode with co-operated instruction by the Cortex-M3. + * @param[in] None + * @return None + **********************************************************************/ +void CLKPWR_DeepPowerDown(void) +{ + /* Deep-Sleep Mode, set SLEEPDEEP bit */ + SCB->SCR = 0x4; + LPC_SC->PCON = 0x03; + /* Deep Power Down Mode*/ + __WFI(); +} + +/** + * @} + */ + +#endif /*_CLKPWR*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_crc.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_crc.c new file mode 100644 index 0000000000000000000000000000000000000000..8d74c052ea859d139038a7dc45083f36c884a054 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_crc.c @@ -0,0 +1,171 @@ +/********************************************************************** +* $Id$ lpc_crc.c 2011-06-02 +*//** +* @file lpc_crc.c +* @brief Contains all functions support for CRC firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _CRC + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_crc.h" +#include "lpc_clkpwr.h" + +/* Private Variables ----------------------------------------------------------- */ +volatile CRC_Type crc_cur_type; + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup CRC_Public_Functions + * @{ + */ +/*********************************************************************//** + * @brief Initialize CRC operation + * @param[in] CRCType CRC standard type, should be: + * - CRC_POLY_CRCCCITT: CRC-CCITT polynomial + * - CRC_POLY_CRC16: CRC-16 polynomial + * - CRC_POLY_CRC32: CRC-32 polynomial + * @return None + **********************************************************************/ +void CRC_Init(CRC_Type CRCType) +{ + if(CRCType == CRC_POLY_CRCCCITT) + { + LPC_CRC->MODE = 0x00; + LPC_CRC->SEED = 0xFFFF; + crc_cur_type = CRC_POLY_CRCCCITT; + } + else if(CRCType == CRC_POLY_CRC16) + { + LPC_CRC->MODE = 0x15; + LPC_CRC->SEED = 0x0000; + crc_cur_type = CRC_POLY_CRC16; + + } + else if(CRCType == CRC_POLY_CRC32) + { + LPC_CRC->MODE = 0x36; + LPC_CRC->SEED = 0xFFFFFFFF; + crc_cur_type = CRC_POLY_CRC32; + } + else + { + //Invalid input parameter + while(1);//error loop + } +} +/*********************************************************************//** + * @brief CRC reset + * @param[in] None + * @return None + **********************************************************************/ +void CRC_Reset(void) +{ + if(crc_cur_type == CRC_POLY_CRCCCITT) + LPC_CRC->SEED = 0xFFFF; + else if (crc_cur_type == CRC_POLY_CRC16) + LPC_CRC->SEED = 0x0000; + else if (crc_cur_type == CRC_POLY_CRC32) + LPC_CRC->SEED = 0xFFFFFFFF; +} + +/*********************************************************************//** + * @brief CRC data checksum calculation + * @param[in] data input data + * @return data checksum result + **********************************************************************/ +uint32_t CRC_CalcDataChecksum(uint32_t data, CRC_WR_SIZE SizeType) +{ + if(SizeType == CRC_WR_8BIT) + LPC_CRC->WR_DATA_BYTE.DATA = (uint8_t)data; + else if(SizeType == CRC_WR_16BIT) + LPC_CRC->WR_DATA_WORD.DATA = (uint16_t)data; + else + LPC_CRC->WR_DATA_DWORD.DATA = data; + return(LPC_CRC->SUM); +} + +/*********************************************************************//** + * @brief CRC block data checksum calculation + * @param[in] blockdata pointer to block input data + * @param[in] blocksize size of block data + * @param[in] SizeType size of data width per write, should be: + - CRC_WR_8BIT : 8-bit write + - CRC_WR_16BIT: 16-bit write + - CRC_WR_32BIT: 32-bit write + * @return block data checksum result + **********************************************************************/ +uint32_t CRC_CalcBlockChecksum(void *block_data, uint32_t block_size, CRC_WR_SIZE data_size) +{ + uint8_t *data = (uint8_t*) block_data; + + while(block_size !=0) { + + switch(data_size) { + + case CRC_WR_8BIT: + { + uint8_t *tmp = data; + LPC_CRC->WR_DATA_BYTE.DATA = *tmp; + data++; + } + break; + case CRC_WR_16BIT: + { + uint16_t *tmp = (uint16_t*)data; + LPC_CRC->WR_DATA_WORD.DATA = *tmp; + data +=2; + } + break; + default: + { + uint32_t *tmp = (uint32_t*)data; + LPC_CRC->WR_DATA_DWORD.DATA = *tmp; + data += 4; + } + break; + } + block_size--; + } + return(LPC_CRC->SUM); +} + +/** + * @} + */ +#endif /*_CRC*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_dac.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..29e126d085cb3f816e2bf3f9334cb7034890b490 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_dac.c @@ -0,0 +1,196 @@ +/********************************************************************** +* $Id$ lpc_dac.c 2011-06-02 +*//** +* @file lpc_dac.c +* @brief Contains all functions support for DAC firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup DAC + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _DAC + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_dac.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +/* Private Functions ---------------------------------------------------------- */ + +/*********************************************************************//** + * @brief Get pointer to DAC peripheral + * @param[in] compId Component ID, normally is zero (0). + * @param[in] pinnum Pin number value, should be in range from 0..31 + * @return Pointer to DAC peripheral component + **********************************************************************/ +static LPC_DAC_TypeDef * DAC_GetPointer(uint8_t compId) +{ + LPC_DAC_TypeDef *pComponent = LPC_DAC; + + return pComponent; +} + + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup DAC_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Initial ADC configuration + * - Maximum current is 700 uA + * - Value to AOUT is 0 + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @return None + ***********************************************************************/ +void DAC_Init(uint8_t DAC_Id) +{ + /* + * Init DAC pin connect + * AOUT on P0.26 + */ + PINSEL_ConfigPin(0, 26, 2); + + PINSEL_SetAnalogPinMode(0,26,ENABLE); + + //Enable DAC for the pin + PINSEL_DacEnable(0, 26, ENABLE); + + //Set maximum current output as default + DAC_SetBias(DAC_Id, DAC_MAX_CURRENT_700uA); +} + +/*********************************************************************//** + * @brief Update value to DAC + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @param[in] dac_value : value 10 bit to be converted to output + * @return None + ***********************************************************************/ +void DAC_UpdateValue (uint8_t DAC_Id,uint32_t dac_value) +{ + uint32_t tmp; + + LPC_DAC_TypeDef* pDac = DAC_GetPointer(DAC_Id); + + tmp = pDac->CR & DAC_BIAS_EN; + + tmp |= DAC_VALUE(dac_value); + + // Update value + pDac->CR = tmp; +} + +/*********************************************************************//** + * @brief Set Maximum current for DAC + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @param[in] bias : 0 is 700 uA + * 1 350 uA + * @return None + ***********************************************************************/ +void DAC_SetBias (uint8_t DAC_Id, uint32_t bias) +{ + LPC_DAC_TypeDef* pDac = DAC_GetPointer(DAC_Id); + + pDac->CR &=~DAC_BIAS_EN; + + if (bias == DAC_MAX_CURRENT_350uA) + { + pDac->CR |= DAC_BIAS_EN; + } +} + +/*********************************************************************//** + * @brief To enable the DMA operation and control DMA timer + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @param[in] DAC_ConverterConfigStruct pointer to DAC_CONVERTER_CFG_Type + * - DBLBUF_ENA : enable/disable DACR double buffering feature + * - CNT_ENA : enable/disable timer out counter + * - DMA_ENA : enable/disable DMA access + * @return None + ***********************************************************************/ +void DAC_ConfigDAConverterControl (uint8_t DAC_Id, DAC_CONVERTER_CFG_Type *DAC_ConverterConfigStruct) +{ + LPC_DAC_TypeDef* pDac = DAC_GetPointer(DAC_Id); + + pDac->CTRL &= ~DAC_DACCTRL_MASK; + + if (DAC_ConverterConfigStruct->DBLBUF_ENA) + pDac->CTRL |= DAC_DBLBUF_ENA; + + if (DAC_ConverterConfigStruct->CNT_ENA) + pDac->CTRL |= DAC_CNT_ENA; + + if (DAC_ConverterConfigStruct->DMA_ENA) + pDac->CTRL |= DAC_DMA_ENA; +} + +/*********************************************************************//** + * @brief Set reload value for interrupt/DMA counter + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @param[in] time_out time out to reload for interrupt/DMA counter + * @return None + ***********************************************************************/ +void DAC_SetDMATimeOut(uint8_t DAC_Id, uint32_t time_out) +{ + LPC_DAC_TypeDef* pDac = DAC_GetPointer(DAC_Id); + + pDac->CNTVAL = DAC_CCNT_VALUE(time_out); +} + + +/*********************************************************************//** + * @brief Check the interrupt/DMA counter is occured or not because of the timer counter + * @param[in] DAC_Id the ID of the DAC component that is using, should be: zero (0) + * @return None + ***********************************************************************/ +uint8_t DAC_IsIntRequested(uint8_t DAC_Id) +{ + LPC_DAC_TypeDef* pDac = DAC_GetPointer(DAC_Id); + + //Return the INT_DMA_REQ bit of D/A control register + return (pDac->CTRL & 0x01); +} + + +/** + * @} + */ +#endif /*_DAC*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_eeprom.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..039a1d4ed3ce5c84b945d7ef91dc70823bab3154 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_eeprom.c @@ -0,0 +1,267 @@ +/********************************************************************** +* $Id$ lpc_eeprom.c 2011-06-02 +*//** +* @file lpc_eeprom.c +* @brief Contains all functions support for EEPROM firmware library on +* LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup EEPROM + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _EEPROM + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_eeprom.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ + +/*********************************************************************//** + * @brief Initial EEPROM + * @param[in] None + * @return None + **********************************************************************/ +void EEPROM_Init(void) +{ + uint32_t val, cclk; + LPC_EEPROM->PWRDWN = 0x0; + /* EEPROM is automate turn on after reset */ + /* Setting clock: + * EEPROM required a 375kHz. This clock is generated by dividing the + * system bus clock. + */ + cclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU); + val = (cclk/375000)-1; + LPC_EEPROM->CLKDIV = val; + + /* Setting wait state */ + val = ((((cclk / 1000000) * 15) / 1000) + 1); + val |= (((((cclk / 1000000) * 55) / 1000) + 1) << 8); + val |= (((((cclk / 1000000) * 35) / 1000) + 1) << 16); + LPC_EEPROM->WSTATE = val; +} + +/*********************************************************************//** + * @brief Write data to EEPROM at specific address + * @param[in] page_offset offset of data in page register(0 - 63) + * page_address page address (0-62) + * mode Write mode, should be: + * - MODE_8_BIT : write 8 bit mode + * - MODE_16_BIT : write 16 bit mode + * - MODE_32_BIT : write 32 bit mode + * data buffer that contain data that will be written to buffer + * count number written data + * @return None + * @note This function actually write data into EEPROM memory and automatically + * write into next page if current page is overflowed + **********************************************************************/ +void EEPROM_Write(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count) +{ + uint32_t i; + uint8_t *tmp8 = (uint8_t *)data; + uint16_t *tmp16 = (uint16_t *)data; + uint32_t *tmp32 = (uint32_t *)data; + + LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG)); + //check page_offset + if(mode == MODE_16_BIT){ + if((page_offset & 0x01)!=0) while(1); + } + else if(mode == MODE_32_BIT){ + if((page_offset & 0x03)!=0) while(1); + } + LPC_EEPROM->ADDR = EEPROM_PAGE_OFFSET(page_offset); + for(i=0;iCMD = EEPROM_CMD_8_BIT_WRITE; + LPC_EEPROM -> WDATA = *tmp8; + tmp8++; + page_offset +=1; + } + else if(mode == MODE_16_BIT){ + LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_WRITE; + LPC_EEPROM -> WDATA = *tmp16; + tmp16++; + page_offset +=2; + } + else{ + LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_WRITE; + LPC_EEPROM -> WDATA = *tmp32; + tmp32++; + page_offset +=4; + } + while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01)); + LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW); + if((page_offset >= EEPROM_PAGE_SIZE)|(i==count-1)){ + //update to EEPROM memory + LPC_EEPROM->INT_CLR_STATUS = (0x1 << EEPROM_ENDOF_PROG); + LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address); + LPC_EEPROM->CMD = EEPROM_CMD_ERASE_PRG_PAGE; + while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_PROG)&0x01)); + LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_PROG); + } + if(page_offset >= EEPROM_PAGE_SIZE) + { + page_offset = 0; + page_address +=1; + LPC_EEPROM->ADDR =0; + if(page_address > EEPROM_PAGE_NUM - 1) page_address = 0; + } + } +} + +/*********************************************************************//** + * @brief Read data to EEPROM at specific address + * @param[in] + * data buffer that contain data that will be written to buffer + * mode Read mode, should be: + * - MODE_8_BIT : read 8 bit mode + * - MODE_16_BIT : read 16 bit mode + * - MODE_32_BIT : read 32 bit mode + * count number read data (bytes) + * @return data buffer that contain data that will be read to buffer + **********************************************************************/ +void EEPROM_Read(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count) +{ + uint32_t i; + uint8_t *tmp8 = (uint8_t *)data; + uint16_t *tmp16 = (uint16_t *)data; + uint32_t *tmp32 = (uint32_t *)data; + + LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG)); + LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset); + if(mode == MODE_8_BIT) + LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH; + else if(mode == MODE_16_BIT){ + LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH; + //check page_offset + if((page_offset &0x01)!=0) + return; + } + else{ + LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH; + //page_offset must be a multiple of 0x04 + if((page_offset & 0x03)!=0) + return; + } + + //read and store data in buffer + for(i=0;i RDATA); + tmp8++; + page_offset +=1; + } + else if (mode == MODE_16_BIT) + { + *tmp16 = (uint16_t)(LPC_EEPROM -> RDATA); + tmp16++; + page_offset +=2; + } + else{ + *tmp32 = (uint32_t)(LPC_EEPROM ->RDATA); + tmp32++; + page_offset +=4; + } + while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01)); + LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW); + if((page_offset >= EEPROM_PAGE_SIZE) && (i < count - 1)) { + page_offset = 0; + page_address++; + LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset); + if(mode == MODE_8_BIT) + LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH; + else if(mode == MODE_16_BIT) + LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH; + else + LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH; + } + } +} + +/*********************************************************************//** + * @brief Erase a page at the specific address + * @param[in] address EEPROM page address (0-62) + * @return data buffer that contain data that will be read to buffer + **********************************************************************/ +void EEPROM_Erase(uint16_t page_address) +{ + uint32_t i; + uint32_t count = EEPROM_PAGE_SIZE/4; + + LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG)); + + //clear page register + LPC_EEPROM->ADDR = EEPROM_PAGE_OFFSET(0); + LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_WRITE; + for(i=0;iWDATA = 0; + while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01)); + LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW); + } + + LPC_EEPROM->INT_CLR_STATUS = (0x1 << EEPROM_ENDOF_PROG); + LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address); + LPC_EEPROM->CMD = EEPROM_CMD_ERASE_PRG_PAGE; + while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_PROG)&0x01)); + LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_PROG); +} + +/*********************************************************************//** + * @brief Enable/Disable EEPROM power down mdoe + * @param[in] NewState PowerDown mode state, should be: + * - ENABLE: Enable power down mode + * - DISABLE: Disable power down mode + * @return None + **********************************************************************/ +void EEPROM_PowerDown(FunctionalState NewState) +{ + if(NewState == ENABLE) + LPC_EEPROM->PWRDWN = 0x1; + else + LPC_EEPROM->PWRDWN = 0x0; +} + +#endif /*_EEPROM*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_emac.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_emac.c new file mode 100644 index 0000000000000000000000000000000000000000..750b487b5477409ea24914cec5f4f39cb244d65d --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_emac.c @@ -0,0 +1,1043 @@ +/********************************************************************** +* $Id$ lpc_emac.c 2011-06-02 +*//** +* @file lpc_emac.c +* @brief Contains all functions support for Ethernet MAC firmware +* library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _EMAC + +#include "lpc_emac.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup EMAC + * @{ + */ + +/************************** PRIVATE VARIABLES *************************/ + + +/* MII Mgmt Configuration register - Clock divider setting */ +const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28, 36, 40, 44, 48, 52, 56, 60, 64 }; + +/* EMAC Config data */ +static EMAC_CFG_Type EMAC_Configs; + + +/* EMAC local DMA Descriptors */ + + +#ifdef __IAR_SYSTEMS_ICC__ +/* Global Tx Buffer data */ +#pragma data_alignment=4 +static uint16_t saFrameBuffers[EMAC_MAX_FRAME_NUM][EMAC_MAX_FRAME_SIZE]; +#else +/* Global Rx Buffer data */ +static uint16_t __attribute__ ((aligned (4))) saFrameBuffers[EMAC_MAX_FRAME_NUM][EMAC_MAX_FRAME_SIZE]; +#endif +static uint32_t sulCurrFrameSz = 0; +static uint8_t sbCurrFrameID = 0; + +/***************************** PRIVATE FUNCTION *****************************/ +static void EMAC_UpdateRxConsumeIndex(void); +static void EMAC_UpdateTxProduceIndex(void); +static uint32_t EMAC_AllocTxBuff(uint16_t nFrameSize, uint8_t bLastFrame); +static uint32_t EMAC_GetRxFrameSize(void); + + +/*********************************************************************//** + * @brief + * @param[in] + * @return + **********************************************************************/ +void rx_descr_init (void) +{ + unsigned int i; + + for (i = 0; i < EMAC_NUM_RX_FRAG; i++) + { + RX_DESC_PACKET(i) = RX_BUF(i); + RX_DESC_CTRL(i) = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN-1); + RX_STAT_INFO(i) = 0; + RX_STAT_HASHCRC(i) = 0; + } + + /* Set EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxDescriptor = RX_DESC_BASE; + LPC_EMAC->RxStatus = RX_STAT_BASE; + LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG-1; + + /* Rx Descriptors Point to 0 */ + LPC_EMAC->RxConsumeIndex = 0; +} + +/*********************************************************************//** + * @brief + * @param[in] + * @return + **********************************************************************/ +void tx_descr_init (void) +{ + unsigned int i; + + for (i = 0; i < EMAC_NUM_TX_FRAG; i++) + { + TX_DESC_PACKET(i) = TX_BUF(i); + TX_DESC_CTRL(i) = 0; + TX_STAT_INFO(i) = 0; + } + + /* Set EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxDescriptor = TX_DESC_BASE; + LPC_EMAC->TxStatus = TX_STAT_BASE; + LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG-1; + + /* Tx Descriptors Point to 0 */ + LPC_EMAC->TxProduceIndex = 0; +} + +/*********************************************************************//** + * @brief Set Station MAC address for EMAC module + * @param[in] abStationAddr Pointer to Station address that contains 6-bytes + * of MAC address. + * @return None + **********************************************************************/ +void setEmacAddr(uint8_t abStationAddr[]) +{ + /* Set the Ethernet MAC Address registers */ + LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4]; + LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2]; + LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0]; +} + + +/************************** GLOBAL/PUBLIC FUNCTIONS *************************/ + +/** @defgroup EMAC_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Write data to PHY + * @param[in] PhyReg PHY register address + * @param[in] Value Register Value + * @return None + **********************************************************************/ +void EMAC_Write_PHY (uint8_t PhyReg, uint16_t Value) +{ + unsigned int tout; + + LPC_EMAC->MADR = ((EMAC_Configs.bPhyAddr & 0x1F) << 8 )| (PhyReg & 0x1F); + LPC_EMAC->MWTD = Value; + + /* Wait utill operation completed */ + tout = 0; + + for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) + { + if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) + { + break; + } + } +} + +/*********************************************************************//** + * @brief Read data from PHY register + * @param[in] PhyReg PHY register address + * @return Register value + **********************************************************************/ +uint16_t EMAC_Read_PHY (uint8_t PhyReg) +{ + unsigned int tout; + + LPC_EMAC->MADR = ((EMAC_Configs.bPhyAddr & 0x1F) << 8 )| (PhyReg & 0x1F); + LPC_EMAC->MCMD = EMAC_MCMD_READ; + + /* Wait until operation completed */ + tout = 0; + for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) + { + if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) + { + break; + } + } + + LPC_EMAC->MCMD = 0; + return (LPC_EMAC->MRDD); +} + +/*********************************************************************//** + * @brief Set Full/Half Duplex Mode + * @param[in] full_duplex 0: Half-duplex, 1: Full-duplex + * @return None + **********************************************************************/ +void EMAC_SetFullDuplexMode(uint8_t full_duplex) +{ + if(full_duplex) + { + LPC_EMAC->MAC2 |= EMAC_MAC2_FULL_DUP; + LPC_EMAC->Command |= EMAC_CR_FULL_DUP; + LPC_EMAC->IPGT = EMAC_IPGT_FULL_DUP; + } + else + { + LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP; + } +} +/*********************************************************************//** + * @brief Set PHY Speed + * @param[in] mode_100Mbps 0: 10Mbps, 1: 100Mbps + * @return None + **********************************************************************/ +void EMAC_SetPHYSpeed(uint8_t mode_100Mbps) +{ + if(mode_100Mbps) + { + LPC_EMAC->SUPP = EMAC_SUPP_SPEED; + } + else + { + LPC_EMAC->SUPP = 0; + } +} + + +/*********************************************************************//** + * @brief Initializes the EMAC peripheral according to the specified +* parameters in the EMAC_ConfigStruct. + * @param[in] EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure +* that contains the configuration information for the +* specified EMAC peripheral. + * @return None + * + * Note: This function will initialize EMAC module according to procedure below: + * - Remove the soft reset condition from the MAC + * - Configure the PHY via the MIIM interface of the MAC + * - Select RMII mode + * - Configure the transmit and receive DMA engines, including the descriptor arrays + * - Configure the host registers (MAC1,MAC2 etc.) in the MAC + * - Enable the receive and transmit data paths + * In default state after initializing, Rx Done and Tx Done interrupt are enabled, + * nad all interrupts are also enabled + * (Ref. from LPC17xx UM) + **********************************************************************/ +int32_t EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct) +{ + /* Initialize the EMAC Ethernet controller. */ + volatile int32_t tout, tmp; + + EMAC_Configs = *EMAC_ConfigStruct; + + /* Set up power for Ethernet module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE); + + /* Enable P1 Ethernet Pins. */ + + /* Reset all EMAC internal modules */ + LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX | + EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES; + + LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM; + + /* A short delay after reset. */ + for (tout = 100; tout; tout--); + + /* Initialize MAC control registers. */ + LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL; + LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN; + LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN; + /* + * Find the clock that close to desired target clock + */ + tmp = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU)/ EMAC_MCFG_MII_MAXCLK; + for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++) + { + if (EMAC_clkdiv[tout] >= tmp) + break; + } + + if(tout >= sizeof (EMAC_clkdiv)) + return ERROR; + tout++; + + // Set Frame size + LPC_EMAC->MAXF = EMAC_ConfigStruct->nMaxFrameSize; + + // Write to MAC configuration register and reset + LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII; + + // release reset + LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII); + LPC_EMAC->CLRT = EMAC_CLRT_DEF; + LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF; + + /* Enable Reduced MII interface. */ + LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM; + + + // Initilialize PHY + if(EMAC_ConfigStruct->pfnPHYInit != NULL) + { + if(EMAC_ConfigStruct->pfnPHYInit(&EMAC_ConfigStruct->PhyCfg) != SUCCESS) + { + return ERROR; + } + } + + // Set EMAC address + setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr); + + /* Initialize Tx and Rx DMA Descriptors */ + rx_descr_init (); + tx_descr_init (); + + // Set Receive Filter register: enable broadcast and multicast + LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN; + + /* Enable Rx Done and Tx Done interrupt for EMAC */ + EMAC_IntCmd((EMAC_INT_RX_OVERRUN | EMAC_INT_RX_ERR | EMAC_INT_RX_FIN \ + | EMAC_INT_RX_DONE | EMAC_INT_TX_UNDERRUN | EMAC_INT_TX_ERR \ + | EMAC_INT_TX_FIN | EMAC_INT_TX_DONE), ENABLE); + + /* Reset all interrupts */ + LPC_EMAC->IntClear = 0xFFFF; + + /* Enable receive and transmit mode of MAC Ethernet core */ + EMAC_TxEnable(); + EMAC_RxEnable(); + + NVIC_EnableIRQ(ENET_IRQn); + + return SUCCESS; +} + + +/*********************************************************************//** + * @brief De-initializes the EMAC peripheral registers to their +* default reset values. + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_DeInit(void) +{ + // Disable all interrupt + LPC_EMAC->IntEnable = 0x00; + + // Clear all pending interrupt + LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP); + + LPC_EMAC->Command = 0; + + /* TurnOff power for Ethernet module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE); +} + +/*********************************************************************//** + * @brief EMAC TX API modules + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_TxEnable( void ) +{ + LPC_EMAC->Command |= EMAC_CR_TX_EN; + return; +} + + +/*********************************************************************//** + * @brief EMAC RX API modules + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_TxDisable( void ) +{ + LPC_EMAC->Command &= ~EMAC_CR_TX_EN; + return; +} + +/*********************************************************************//** + * @brief EMAC RX API modules + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_RxEnable( void ) +{ + LPC_EMAC->Command |= EMAC_CR_RX_EN; + LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN; + return; +} + +/*********************************************************************//** + * @brief EMAC RX API modules + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_RxDisable( void ) +{ + LPC_EMAC->Command &= ~EMAC_CR_RX_EN; + LPC_EMAC->MAC1 &= ~EMAC_MAC1_REC_EN; + return; +} + +/*********************************************************************//** + * @brief Get the status of given buffer. + * @param[in] idx Buffer index + * @return EMAC_BUFF_AVAILABLE/EMAC_BUFF_FULL/EMAC_BUFF_PARTIAL_FULL + * + **********************************************************************/ +EMAC_BUFF_STATUS EMAC_GetBufferSts(EMAC_BUFF_IDX idx) +{ + uint32_t consume_idx, produce_idx; + uint32_t max_frag_num; + + // Get the consume index, produce index and the buffer size + if(idx == EMAC_TX_BUFF) + { + consume_idx = LPC_EMAC->TxConsumeIndex; + produce_idx = LPC_EMAC->TxProduceIndex; + max_frag_num = LPC_EMAC->TxDescriptorNumber + 1; + } + else + { + consume_idx = LPC_EMAC->RxConsumeIndex; + produce_idx = LPC_EMAC->RxProduceIndex; + max_frag_num = LPC_EMAC->RxDescriptorNumber + 1; + } + + // empty + if(consume_idx == produce_idx) + return EMAC_BUFF_EMPTY; + + // Full + if(consume_idx == 0 && + produce_idx == max_frag_num - 1) + return EMAC_BUFF_FULL; + + // Wrap-around + if(consume_idx == produce_idx + 1) + return EMAC_BUFF_FULL; + + return EMAC_BUFF_PARTIAL_FULL; +} + +/*********************************************************************//** + * @brief Allocate a descriptor for sending frame and get the coressponding buffer address + * @param[in] FrameSize The size of frame you want to send + * @return Address of the TX_DESC_PACKET buffer + **********************************************************************/ + uint32_t EMAC_AllocTxBuff(uint16_t nFrameSize, uint8_t bLastFrame) +{ + uint32_t idx; + uint32_t dp; + volatile uint32_t i; + + idx = LPC_EMAC->TxProduceIndex; + + while(EMAC_GetBufferSts(EMAC_TX_BUFF) == EMAC_BUFF_FULL) + { + for(i = 0; i < 1000000; i++) ; + } + + dp = TX_DESC_PACKET(idx); + + if(bLastFrame) + TX_DESC_CTRL(idx) = ((nFrameSize-1) & EMAC_TCTRL_SIZE) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST); + else + TX_DESC_CTRL(idx) = ((nFrameSize-1) & EMAC_TCTRL_SIZE) | (EMAC_TCTRL_INT); + + return dp; +} + +/*********************************************************************//** + * @brief Increase the TxProduceIndex (after writting to the Transmit buffer + * to enable the Transmit buffer) and wrap-around the index if + * it reaches the maximum Transmit Number + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_UpdateTxProduceIndex(void) +{ + // Get current Tx produce index + uint32_t idx = LPC_EMAC->TxProduceIndex; + + /* Start frame transmission */ + if (++idx == LPC_EMAC->TxDescriptorNumber + 1) idx = 0; + LPC_EMAC->TxProduceIndex = idx; +} + +/*********************************************************************//** + * @brief Get current status value of receive data (due to TxProduceIndex) + * @param[in] None + * @return Current value of receive data (due to TxProduceIndex) + **********************************************************************/ +uint32_t EMAC_GetTxFrameStatus(void) +{ + uint32_t idx; + + idx = LPC_EMAC->TxProduceIndex; + return (TX_STAT_INFO(idx)); +} + +/*********************************************************************//** + * @brief Write data to Tx packet data buffer at current index due to + * TxProduceIndex + * @param[in] pDataStruct store the address and the size of buffer that saves data. + * @return None + **********************************************************************/ +void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct) +{ + uint16_t* pDest; + uint16_t* pSource = (uint16_t*)pDataStruct->pbDataBuf; + uint32_t size = pDataStruct->ulDataLen; + int32_t frame_num; + uint32_t tmp; + uint32_t max_frame_size = LPC_EMAC->MAXF; + + size = (size + 1) & 0xFFFE; // round Size up to next even number + frame_num = size/max_frame_size; + + if(size == 0) + return; + + while(frame_num >= 0) + { + tmp = (frame_num > 0)? max_frame_size:size; + + if(tmp == 0) + break; + + // Setup descriptors and data + if(frame_num == 0) + pDest = (uint16_t*)EMAC_AllocTxBuff(tmp, 1); // last frame + else + pDest = (uint16_t*)EMAC_AllocTxBuff(tmp, 0); + + // Copy data + while (tmp > 0) + { + *pDest++ = *pSource++; + tmp -= 2; + } + frame_num--; + size -= tmp; + + // Update produce index + EMAC_UpdateTxProduceIndex(); + } +} + + +/*********************************************************************//** + * @brief Get current status value of receive data (due to RxConsumeIndex) + * @param[in] None + * @return Current value of receive data (due to RxConsumeIndex) + **********************************************************************/ +uint32_t EMAC_GetRxFrameStatus(void) +{ + uint32_t idx; + + idx = LPC_EMAC->RxConsumeIndex; + return (RX_STAT_INFO(idx)); +} + + +/*********************************************************************//** + * @brief Get size of current Received data in received buffer (due to + * RxConsumeIndex) + * @param[in] None + * @return Size of received data + **********************************************************************/ +uint32_t EMAC_GetRxFrameSize(void) +{ + uint32_t idx; + + idx = LPC_EMAC->RxConsumeIndex; + + return (((RX_STAT_INFO(idx)) & EMAC_RINFO_SIZE)+1); +} + + +/*********************************************************************//** + * @brief Get the address of TX_DESC_PACKET buffer so that user can access from application + * @param[in] None + * @return Address of the TX_DESC_PACKET buffer + **********************************************************************/ + +uint32_t EMAC_GetRxBuffer(void) +{ + uint32_t idx; + + idx = LPC_EMAC->RxConsumeIndex; + + return RX_DESC_PACKET(idx); + } + + +/*********************************************************************//** + * @brief Increase the RxConsumeIndex (after reading the Receive buffer + * to release the Receive buffer) and wrap-around the index if + * it reaches the maximum Receive Number + * @param[in] None + * @return None + **********************************************************************/ +void EMAC_UpdateRxConsumeIndex(void) +{ + // Get current Rx consume index + uint32_t idx = LPC_EMAC->RxConsumeIndex; + + /* Release frame from EMAC buffer */ + if (++idx == EMAC_NUM_RX_FRAG) idx = 0; + + LPC_EMAC->RxConsumeIndex = idx; +} + +/*********************************************************************//** + * @brief Standard EMAC IRQ Handler. This sub-routine will check + * these following interrupt and call the call-back function + * if they're already installed: + * - Overrun Error interrupt in RX Queue + * - Receive Error interrupt: AlignmentError, RangeError, + * LengthError, SymbolError, CRCError or NoDescriptor or Overrun + * - RX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex) + * - Receive Done interrupt: Read received frame to the internal buffer + * - Transmit Under-run interrupt + * - Transmit errors interrupt : LateCollision, ExcessiveCollision + * and ExcessiveDefer, NoDescriptor or Under-run + * - TX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex) + * - Transmit Done interrupt + * - Interrupt triggered by software + * - Interrupt triggered by a Wakeup event detected by the receive filter + * @param[in] None + * @return None + **********************************************************************/ +void ENET_IRQHandler(void) +{ + /* EMAC Ethernet Controller Interrupt function. */ + uint32_t int_stat; + int32_t RxLen; + + // Get EMAC interrupt status + while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0) + { + // Clear interrupt status + LPC_EMAC->IntClear = int_stat; + + if(int_stat & (EMAC_INT_RX_OVERRUN |EMAC_INT_RX_ERR )) + { + uint32_t ulFrameSts = EMAC_GetRxFrameStatus(); + uint32_t ulErrCode = 0; + + ulErrCode |= (ulFrameSts & EMAC_RINFO_CRC_ERR) ? EMAC_CRC_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_SYM_ERR) ? EMAC_SYMBOL_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_LEN_ERR) ? EMAC_LENGTH_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_ALIGN_ERR) ? EMAC_ALIGN_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_OVERRUN) ? EMAC_OVERRUN_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_NO_DESCR) ? EMAC_RX_NO_DESC_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_RINFO_FAIL_FILT) ? EMAC_FILTER_FAILED_ERR:0; + + if(ulErrCode == 0) + { + /* Note: + * The EMAC doesn't distinguish the frame type and frame length, + * so, e.g. when the IP(0x8000) or ARP(0x0806) packets are received, + * it compares the frame type with the max length and gives the + * "Range" error. In fact, this bit is not an error indication, + * but simply a statement by the chip regarding the status of + * the received frame + */ + int_stat &= ~EMAC_INT_RX_ERR; + } + else + { + if(EMAC_Configs.pfnErrorReceive != NULL) + EMAC_Configs.pfnErrorReceive(ulErrCode); + } + } + + if(int_stat & (EMAC_INT_TX_UNDERRUN|EMAC_INT_TX_ERR )) + { + uint32_t ulFrameSts = EMAC_GetTxFrameStatus(); + uint32_t ulErrCode = 0; + + ulErrCode |= (ulFrameSts & EMAC_TINFO_EXCESS_DEF) ? EMAC_EXCESSIVE_DEFER_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_TINFO_EXCESS_COL) ? EMAC_EXCESSIVE_COLLISION_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_TINFO_LATE_COL) ? EMAC_LATE_COLLISION_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_TINFO_UNDERRUN) ? EMAC_UNDERRUN_ERR:0; + ulErrCode |= (ulFrameSts & EMAC_TINFO_NO_DESCR) ? EMAC_TX_NO_DESC_ERR:0; + if(EMAC_Configs.pfnErrorReceive != NULL) + EMAC_Configs.pfnErrorReceive(ulErrCode); + } + + if(int_stat & EMAC_INT_RX_DONE) + { + + /* Packet received. */ + if(EMAC_GetBufferSts(EMAC_RX_BUFF) != EMAC_BUFF_EMPTY) + { + // Get data size + RxLen = EMAC_GetRxFrameSize(); + if(RxLen > 0) + { + // trip out 4-bytes CRC field, note that length in (-1) style format + RxLen -= 3; + + if((EMAC_GetRxFrameStatus() & EMAC_RINFO_ERR_MASK )== 0) + { + uint16_t *pDest = (uint16_t*) &saFrameBuffers[sbCurrFrameID][sulCurrFrameSz]; + uint16_t *pSource = (uint16_t*)EMAC_GetRxBuffer(); + sulCurrFrameSz += RxLen; + + if(sulCurrFrameSz >= EMAC_MAX_FRAME_SIZE) + { + sulCurrFrameSz = 0; + if(EMAC_Configs.pfnErrorReceive != NULL) + EMAC_Configs.pfnErrorReceive(EMAC_LENGTH_ERR); + } + else + { + // Copy data + while (RxLen > 0) + { + *pDest++ = *pSource++; + RxLen -= 2; + } + if(EMAC_GetRxFrameStatus() & EMAC_RINFO_LAST_FLAG) + { + + if(EMAC_Configs.pfnFrameReceive != NULL) + { + EMAC_Configs.pfnFrameReceive((uint16_t*)saFrameBuffers[sbCurrFrameID], sulCurrFrameSz); + } + sulCurrFrameSz = 0; + sbCurrFrameID ++; + if(sbCurrFrameID >= EMAC_MAX_FRAME_NUM) + sbCurrFrameID = 0; + } + /* Release frame from EMAC buffer */ + EMAC_UpdateRxConsumeIndex(); + } + } + } + } + + } + + if(int_stat & EMAC_INT_TX_FIN && (EMAC_Configs.pfnTransmitFinish != NULL)) + { + EMAC_Configs.pfnTransmitFinish(); + } + + if(int_stat & EMAC_INT_SOFT_INT && (EMAC_Configs.pfnSoftInt!= NULL)) + { + EMAC_Configs.pfnSoftInt(); + } + + if(int_stat & EMAC_INT_WAKEUP && (EMAC_Configs.pfnWakeup!= NULL)) + { + EMAC_Configs.pfnWakeup(); + } + + } +} + + +/*********************************************************************//** + * @brief Enable/Disable hash filter functionality for specified destination + * MAC address in EMAC module + * @param[in] dstMAC_addr Pointer to the first MAC destination address, should + * be 6-bytes length, in order LSB to the MSB + * @param[in] NewState New State of this command, should be: + * - ENABLE. + * - DISABLE. + * @return None + * + * Note: + * The standard Ethernet cyclic redundancy check (CRC) function is calculated from + * the 6 byte destination address in the Ethernet frame (this CRC is calculated + * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of + * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access + * the hash table: it is used as an index in the 64 bit HashFilter register that has been + * programmed with accept values. If the selected accept value is 1, the frame is + * accepted. + **********************************************************************/ +void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState) +{ + uint32_t *pReg; + uint32_t tmp; + int32_t crc; + + // Calculate the CRC from the destination MAC address + crc = EMAC_CRCCalc(dstMAC_addr, 6); + // Extract the value from CRC to get index value for hash filter table + crc = (crc >> 23) & 0x3F; + + pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \ + : ((uint32_t *)&LPC_EMAC->HashFilterL); + tmp = (crc > 31) ? (crc - 32) : crc; + if (NewState == ENABLE) + { + (*pReg) |= (1UL << tmp); + } + else + { + (*pReg) &= ~(1UL << tmp); + } + +} + + +/*********************************************************************//** + * @brief Calculates CRC code for number of bytes in the frame + * @param[in] frame_no_fcs Pointer to the first byte of the frame + * @param[in] frame_len length of the frame without the FCS + * @return the CRC as a 32 bit integer + **********************************************************************/ +int32_t EMAC_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len) +{ + int i; // iterator + int j; // another iterator + char byte; // current byte + int crc; // CRC result + int q0, q1, q2, q3; // temporary variables + + crc = 0xFFFFFFFF; + + for (i = 0; i < frame_len; i++) + { + byte = *frame_no_fcs++; + for (j = 0; j < 2; j++) + { + if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) + { + q3 = 0x04C11DB7; + } + else + { + q3 = 0x00000000; + } + + if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) + { + q2 = 0x09823B6E; + } + else + { + q2 = 0x00000000; + } + + if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) + { + q1 = 0x130476DC; + } + else + { + q1 = 0x00000000; + } + + if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) + { + q0 = 0x2608EDB8; + } + else + { + q0 = 0x00000000; + } + + crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0; + + byte >>= 4; + } + } + + return crc; +} + +/*********************************************************************//** + * @brief Enable/Disable Filter mode for each specified type EMAC peripheral + * @param[in] ulFilterMode Filter mode, should be: + * - EMAC_RFC_UCAST_EN: all frames of unicast types + * will be accepted + * - EMAC_RFC_BCAST_EN: broadcast frame will be + * accepted + * - EMAC_RFC_MCAST_EN: all frames of multicast + * types will be accepted + * - EMAC_RFC_UCAST_HASH_EN: The imperfect hash + * filter will be applied to unicast addresses + * - EMAC_RFC_MCAST_HASH_EN: The imperfect hash + * filter will be applied to multicast addresses + * - EMAC_RFC_PERFECT_EN: the destination address + * will be compared with the 6 byte station address + * programmed in the station address by the filter + * - EMAC_RFC_MAGP_WOL_EN: the result of the magic + * packet filter will generate a WoL interrupt when + * there is a match + * - EMAC_RFC_PFILT_WOL_EN: the result of the perfect address + * matching filter and the imperfect hash filter will + * generate a WoL interrupt when there is a match + * @param[in] NewState New State of this command, should be: + * - ENABLE + * - DISABLE + * @return None + **********************************************************************/ +void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + LPC_EMAC->RxFilterCtrl |= ulFilterMode; + + if((ulFilterMode & EMAC_RFC_MCAST_HASH_EN) && + ((ulFilterMode & EMAC_RFC_MCAST_EN) == 0)) + { + LPC_EMAC->RxFilterCtrl &= ~EMAC_RFC_MCAST_EN; + } + if((ulFilterMode & EMAC_RFC_UCAST_HASH_EN) && + ((ulFilterMode & EMAC_RFC_UCAST_EN) == 0)) + { + LPC_EMAC->RxFilterCtrl &= ~EMAC_RFC_UCAST_EN; + } + } + else + { + LPC_EMAC->RxFilterCtrl &= ~ulFilterMode; + } +} + +/*********************************************************************//** + * @brief Get status of Wake On LAN Filter for each specified + * type in EMAC peripheral, clear this status if it is set + * @param[in] ulFilterMode WoL Filter mode, should be: + * - EMAC_WOL_UCAST: unicast frames caused WoL + * - EMAC_WOL_UCAST: broadcast frame caused WoL + * - EMAC_WOL_MCAST: multicast frame caused WoL + * - EMAC_WOL_UCAST_HASH: unicast frame that passes the + * imperfect hash filter caused WoL + * - EMAC_WOL_MCAST_HASH: multicast frame that passes the + * imperfect hash filter caused WoL + * - EMAC_WOL_PERFECT:perfect address matching filter + * caused WoL + * - EMAC_WOL_RX_FILTER: the receive filter caused WoL + * - EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL + * @return SET/RESET + **********************************************************************/ +FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode) +{ + if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) + { + LPC_EMAC->RxFilterWoLClear = ulWoLMode; + + return SET; + } + else + { + return RESET; + } +} + + + + + + +/*********************************************************************//** + * @brief Enable/Disable interrupt for each type in EMAC + * @param[in] ulIntType Interrupt Type, should be: + * - EMAC_INT_RX_OVERRUN: Receive Overrun + * - EMAC_INT_RX_ERR: Receive Error + * - EMAC_INT_RX_FIN: Receive Descriptor Finish + * - EMAC_INT_RX_DONE: Receive Done + * - EMAC_INT_TX_UNDERRUN: Transmit Under-run + * - EMAC_INT_TX_ERR: Transmit Error + * - EMAC_INT_TX_FIN: Transmit descriptor finish + * - EMAC_INT_TX_DONE: Transmit Done + * - EMAC_INT_SOFT_INT: Software interrupt + * - EMAC_INT_WAKEUP: Wakeup interrupt + * @param[in] NewState New State of this function, should be: + * - ENABLE. + * - DISABLE. + * @return None + **********************************************************************/ +void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + LPC_EMAC->IntEnable |= ulIntType; + } + else + { + LPC_EMAC->IntEnable &= ~(ulIntType); + } +} + +/*********************************************************************//** + * @brief Check whether if specified interrupt flag is set or not + * for each interrupt type in EMAC and clear interrupt pending + * if it is set. + * @param[in] ulIntType Interrupt Type, should be: + * - EMAC_INT_RX_OVERRUN: Receive Overrun + * - EMAC_INT_RX_ERR: Receive Error + * - EMAC_INT_RX_FIN: Receive Descriptor Finish + * - EMAC_INT_RX_DONE: Receive Done + * - EMAC_INT_TX_UNDERRUN: Transmit Under-run + * - EMAC_INT_TX_ERR: Transmit Error + * - EMAC_INT_TX_FIN: Transmit descriptor finish + * - EMAC_INT_TX_DONE: Transmit Done + * - EMAC_INT_SOFT_INT: Software interrupt + * - EMAC_INT_WAKEUP: Wakeup interrupt + * @return New state of specified interrupt (SET or RESET) + **********************************************************************/ +IntStatus EMAC_IntGetStatus(uint32_t ulIntType) +{ + if (LPC_EMAC->IntStatus & ulIntType) + { + LPC_EMAC->IntClear = ulIntType; + return SET; + } + else + { + return RESET; + } +} + + + +/** + * @} + */ + +/** + * @} + */ +#endif /*_EMAC*/ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_emc.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_emc.c new file mode 100644 index 0000000000000000000000000000000000000000..0ede2221e7c91174dccbf23d51bd7c66db9fd685 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_emc.c @@ -0,0 +1,1398 @@ +/********************************************************************** +* $Id$ lpc_emc.c 2011-06-02 +*//** +* @file lpc_emc.c +* @brief Contains all functions support for EMC firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _EMC + +#include "lpc_emc.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup EMC + * @{ + */ + +/** @defgroup EMC_Public_Functions + * @{ + */ + +/********************************************************************* + * @brief Calculate refresh timer (the multiple of 16 CCLKs) + * @param[in] freq - frequency of EMC Clk + * @param[in] time - micro second + * @return None + **********************************************************************/ +uint32_t EMC_SDRAM_REFRESH(uint32_t time) +{ + uint32_t emc_freq = CLKPWR_GetCLK(CLKPWR_CLKTYPE_EMC); + return (((uint64_t)((uint64_t)time * emc_freq)/16000000ull)+1); +} +/********************************************************************* + * @brief Calculate EMC Clock from nano second + * @param[in] time - nano second + * @return None + **********************************************************************/ +uint32_t EMC_NS2CLK(uint32_t time){ + uint32_t emc_freq = CLKPWR_GetCLK(CLKPWR_CLKTYPE_EMC); + return (((uint64_t)time*emc_freq/1000000000ull)); +} + +/********************************************************************* + * @brief Power on EMC Block + * @param[in] None + * @return None + **********************************************************************/ +EMC_FUNC_CODE EMC_PwrOn(void) +{ + // If CPU clock is > 80 MHz, then divide it by two to create the EMC clock + if(CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) > 80000000) { + CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 1); // CPU clock / 2 + } else { + CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 0); // Same clock as CPU + } + + // Power on + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCEMC, ENABLE); + + // Enable + LPC_EMC->Control = EMC_Control_E; + + return EMC_FUNC_OK; +} +/*********************************************************************//** + * @brief Initialize external dynamic memory + * @param[in] pConfig Configuration + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM/EMC_FUNC_ERR + **********************************************************************/ +EMC_FUNC_CODE DynMem_Init(EMC_DYN_MEM_Config_Type* pConfig) +{ + uint32_t i = 0; + EMC_FUNC_CODE ret = EMC_FUNC_OK; + + /* Pin configuration: + * P2.16 - /EMC_CAS + * P2.17 - /EMC_RAS + * P2.18 - EMC_CLK[0] + * P2.19 - EMC_CLK[1] + * + * P2.20 - EMC_DYCS0 + * P2.21 - EMC_DYCS1 + * P2.22 - EMC_DYCS2 + * P2.23 - EMC_DYCS3 + * + * P2.24 - EMC_CKE0 + * P2.25 - EMC_CKE1 + * P2.26 - EMC_CKE2 + * P2.27 - EMC_CKE3 + * + * P2.28 - EMC_DQM0 + * P2.29 - EMC_DQM1 + * P2.30 - EMC_DQM2 + * P2.31 - EMC_DQM3 + * + * P3.0-P3.31 - EMC_D[0-31] + * P4.0-P4.23 - EMC_A[0-23] + * P5.0-P5.1 - EMC_A[24-25] + * + * P4.25 - EMC_WE + */ + PINSEL_ConfigPin(2,16,1); + PINSEL_ConfigPin(2,17,1); + PINSEL_ConfigPin(2,18,1); + PINSEL_ConfigPin(2,19,1); + PINSEL_ConfigPin(2,20,1); + PINSEL_ConfigPin(2,21,1); + PINSEL_ConfigPin(2,22,1); + PINSEL_ConfigPin(2,23,1); + PINSEL_ConfigPin(2,24,1); + PINSEL_ConfigPin(2,25,1); + PINSEL_ConfigPin(2,26,1); + PINSEL_ConfigPin(2,27,1); + PINSEL_ConfigPin(2,28,1); + PINSEL_ConfigPin(2,29,1); + PINSEL_ConfigPin(2,30,1); + PINSEL_ConfigPin(2,31,1); + + for(i = 0; i < 32; i++) + { + PINSEL_ConfigPin(3,i,1); + PINSEL_ConfigPin(4,i,1); + } + PINSEL_ConfigPin(5,0,1); + PINSEL_ConfigPin(5,1,1); + + + // Power On + ret |= EMC_PwrOn(); + + /*Init SDRAM controller*/ + LPC_SC->EMCDLYCTL |= (8<<0); + /*Set data read delay*/ + LPC_SC->EMCDLYCTL |=(8<<8); + LPC_SC->EMCDLYCTL |= (0x08 <<16); + + ret |= EMC_ConfigEndianMode(EMC_Config_Little_Endian_Mode); + + /* Dynamic memory setting */ + ret |= EMC_DynCtrlSelfRefresh(EMC_DYNAMIC_CTRL_SR_NORMALMODE); + ret |= EMC_DynCtrlPowerDownMode(EMC_DYNAMIC_CTRL_DP_NORMAL); + ret |= EMC_DynCtrlClockEnable(EMC_DYNAMIC_CTRL_CE_ALLCLK_HI); + ret |= EMC_DynCtrlMMC(EMC_DYNAMIC_CTRL_MMC_CLKOUT_ENABLED); + ret |= EMC_DynCtrlClockControl(EMC_DYNAMIC_CTRL_CE_CLKOUT_CONT); + + /* Timing */ + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_REFRESH_TIMER, pConfig->RefreshTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_READ_CONFIG, pConfig->ReadConfig); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TRP, pConfig->PrechargeCmdPeriod); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TRAS, pConfig->Active2PreChargeTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TSREX, pConfig->SeftRefreshExitTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TAPR, pConfig->DataOut2ActiveTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TDAL, pConfig->DataIn2ActiveTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TWR, pConfig->WriteRecoveryTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TRC, pConfig->Active2ActivePeriod); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TRFC, pConfig->AutoRefrehPeriod); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TXSR, pConfig->ExitSelfRefreshTime); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TRRD, pConfig->ActiveBankLatency); + ret |= EMC_SetDynMemoryParameter(EMC_DYN_MEM_TMRD, pConfig->LoadModeReg2Active); + ret |= EMC_DynMemRAS(pConfig->CSn,pConfig->RASLatency); + ret |= EMC_DynMemCAS(pConfig->CSn,pConfig->CASLatency); + + ret |= EMC_DynMemConfigMD(pConfig->CSn,EMC_DYNAMIC_CFG_MEMDEV_SDRAM); + ret |= EMC_DynMemConfigAM(pConfig->CSn, pConfig->AddrBusWidth, pConfig->AddrMap, pConfig->DataWidth, pConfig->ChipSize); + + return ret; +} + +/*********************************************************************//** + * @brief Initialize external static memory + * @param[in] pConfig Configuration + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM/EMC_FUNC_ERR + **********************************************************************/ +EMC_FUNC_CODE StaticMem_Init(EMC_STATIC_MEM_Config_Type* pConfig) +{ + uint32_t i; + EMC_FUNC_CODE ret = EMC_FUNC_OK; + /* Pin configuration: + * P4.30 - /EMC_CS0 + * P4.31 - /EMC_CS1 + * P2.14 - /EMC_CS2 + * P2.15 - /EMC_CS3 + * + * + * P3.0-P3.31 - EMC_D[0-31] + * P4.0-P4.23 - EMC_A[0-23] + * P5.0-P5.1 - EMC_A[24-25] + * + * P4.24 - /EMC_OE + * P4.25 - /EMC_WE + * + + */ + PINSEL_ConfigPin(2,14,1); + PINSEL_ConfigPin(2,15,1); + + for(i = 0; i < 32; i++) + { + PINSEL_ConfigPin(3,i,1); + PINSEL_ConfigPin(4,i,1); + } + PINSEL_ConfigPin(5,0,1); + PINSEL_ConfigPin(5,1,1); + + // Power On + ret |= EMC_PwrOn(); + + // Configuration + if(pConfig->AddressMirror) + { + LPC_EMC->Control |= EMC_Control_M; + } + + ret |= EMC_StaMemConfigMW(pConfig->CSn,pConfig->DataWidth); + + if(pConfig->PageMode) + ret |= EMC_StaMemConfigPM(pConfig->CSn,EMC_CFG_PM_ASYNC_ENABLE); + else + ret |= EMC_StaMemConfigPM(pConfig->CSn,EMC_CFG_PM_DISABLE); + + if(pConfig->ByteLane) + ret |= EMC_StaMemConfigPB(pConfig->CSn, EMC_CFG_BYTELAND_READ_BITSLOW); + else + ret |= EMC_StaMemConfigPB(pConfig->CSn, EMC_CFG_BYTELAND_READ_BITSHIGH); + + if(pConfig->ExtendedWait) + ret |= EMC_StaMemConfigEW(pConfig->CSn,EMC_CFG_EW_ENABLED); + else + ret |= EMC_StaMemConfigEW(pConfig->CSn,EMC_CFG_EW_DISABLED); + + // Timing + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITWEN, pConfig->WaitWEn); + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITOEN, pConfig->WaitOEn); + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITRD, pConfig->WaitRd); + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITPAGE, pConfig->WaitPage); + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITWR, pConfig->WaitWr); + ret |= EMC_SetStaMemoryParameter(pConfig->CSn,EMC_STA_MEM_WAITTURN, pConfig->WaitTurn); + + + return ret; +} + +/*********************************************************************//** + * @brief EMC initialize (power on block, config EMC pins). + * @param[in] None + * @return None + **********************************************************************/ +EMC_FUNC_CODE EMC_Init(void) +{ + uint8_t i; + // If CPU clock is > 80 MHz, then divide it by two to create the EMC clock + if(CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) > 80000000) { + CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 1); // CPU clock / 2 + } else { + CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 0); // Same clock as CPU + } + + LPC_SC->PCONP |= 0x00000800; + LPC_SC->EMCDLYCTL = 0x00001010; + LPC_EMC->Control = 0x00000001; + LPC_EMC->Config = 0x00000000; + + /* Pin configuration: + * P2.14 - /EMC_CS2 + * P2.15 - /EMC_CS3 + * + * P2.16 - /EMC_CAS + * P2.17 - /EMC_RAS + * P2.18 - EMC_CLK[0] + * P2.19 - EMC_CLK[1] + * + * P2.20 - EMC_DYCS0 + * P2.21 - EMC_DYCS1 + * P2.22 - EMC_DYCS2 + * P2.23 - EMC_DYCS3 + * + * P2.24 - EMC_CKE0 + * P2.25 - EMC_CKE1 + * P2.26 - EMC_CKE2 + * P2.27 - EMC_CKE3 + * + * P2.28 - EMC_DQM0 + * P2.29 - EMC_DQM1 + * P2.30 - EMC_DQM2 + * P2.31 - EMC_DQM3 + * + * P3.0-P3.31 - EMC_D[0-31] + * P4.0-P4.23 - EMC_A[0-23] + * P5.0-P5.1 - EMC_A[24-25] + * + * P4.24 - /EMC_OE + * P4.25 - /EMC_WE + * + * P4.30 - /EMC_CS0 + * P4.31 - /EMC_CS1 + */ + PINSEL_ConfigPin(2,14,1); + PINSEL_ConfigPin(2,15,1); + PINSEL_ConfigPin(2,16,1); + PINSEL_ConfigPin(2,17,1); + PINSEL_ConfigPin(2,18,1); + PINSEL_ConfigPin(2,19,1); + PINSEL_ConfigPin(2,20,1); + PINSEL_ConfigPin(2,21,1); + PINSEL_ConfigPin(2,22,1); + PINSEL_ConfigPin(2,23,1); + PINSEL_ConfigPin(2,24,1); + PINSEL_ConfigPin(2,25,1); + PINSEL_ConfigPin(2,26,1); + PINSEL_ConfigPin(2,27,1); + PINSEL_ConfigPin(2,28,1); + PINSEL_ConfigPin(2,29,1); + PINSEL_ConfigPin(2,30,1); + PINSEL_ConfigPin(2,31,1); + + for(i = 0; i < 32; i++) + { + PINSEL_ConfigPin(3,i,1); + PINSEL_ConfigPin(4,i,1); + } + PINSEL_ConfigPin(5,0,1); + PINSEL_ConfigPin(5,1,1); + + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Configure Little Endian/Big Endian mode for EMC + * + * @param[in] endia_mode Endian mode, should be: + * + * - EMC_Config_Little_Endian_Mode: Little-endian mode + * + * - EMC_Config_Big_Endian_Mode : Big-endian mode + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_ConfigEndianMode(uint32_t endian_mode) +{ + LPC_EMC->Config &= ~(EMC_Config_Endian_Mask); + LPC_EMC->Config |= (endian_mode&EMC_Config_Endian_Mask); + return EMC_FUNC_OK; +} + +/****************** Group of Dynamic control functions************************/ + +/*********************************************************************//** + * @brief Set the dsvalue for dynamic clock enable bit + * + * @param[in] clock_enable clock enable mode, should be: + * + * - EMC_DYNAMIC_CTRL_CE_SAVEPWR: Clock enable of idle devices + * are deasserted to save power + * + * - EMC_DYNAMIC_CTRL_CE_ALLCLK_HI: All clock enables are driven + * HIGH continuously + * + * @return EMC_FUNC_CODE + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlClockEnable(uint32_t clock_enable) +{ + LPC_EMC->DynamicControl &= ~(EMC_DYNAMIC_CTRL_MEMCLK_EN_BMASK); + LPC_EMC->DynamicControl |= clock_enable & EMC_DYNAMIC_CTRL_MEMCLK_EN_BMASK; + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Set the value for dynamic memory clock control: stops or + * runs continuously + * + * @param[in] clock_control clock control mode, should be: + * + * - EMC_DYNAMIC_CTRL_CS_CLKOUT_STOP: CLKOUT stops when all + * SDRAMs are idle and during self-refresh mode + * + * - EMC_DYNAMIC_CTRL_CS_CLKOUT_CONT: CLKOUT runs continuously + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlClockControl(int32_t clock_control) +{ + LPC_EMC->DynamicControl &= ~EMC_DYNAMIC_CTRL_CLKCTRL_BMASK; + LPC_EMC->DynamicControl |= clock_control & EMC_DYNAMIC_CTRL_CLKCTRL_BMASK; + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Switch the Self-refresh mode between normal and self-refresh mode + * + * @param[in] self_refresh_mode self refresh mode, should be: + * + * - EMC_DYNAMIC_CTRL_SR_NORMALMODE: Normal mode + * + * - EMC_DYNAMIC_CTRL_SR_SELFREFRESH: Enter self-refresh mode + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlSelfRefresh(uint32_t self_refresh_mode) +{ + LPC_EMC->DynamicControl &= ~EMC_DYNAMIC_CTRL_SELFREFRESH_REQ_BMASK; + LPC_EMC->DynamicControl =self_refresh_mode & EMC_DYNAMIC_CTRL_SELFREFRESH_REQ_BMASK; + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Enable/disable CLKOUT + * + * @param[in] MMC_val Memory clock control mode, should be: + * + * - EMC_DYNAMIC_CTRL_MMC_CLKOUT_ENABLED: CLKOUT enabled + * + * - EMC_DYNAMIC_CTRL_MMC_CLKOUT_DISABLED: CLKOUT disabled + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlMMC(uint32_t MMC_val) +{ + LPC_EMC->DynamicControl &= ~EMC_DYNAMIC_CTRL_MMC_CLKOUTCTRL_BMASK; + LPC_EMC->DynamicControl |=MMC_val & EMC_DYNAMIC_CTRL_MMC_CLKOUTCTRL_BMASK; + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Issue SDRAM command + * + * @param[in] SDRAM_command Command mode, should be: + * + * - EMC_DYNAMIC_CTRL_SDRAM_NORMAL: Issue SDRAM NORMAL operation command + * + * - EMC_DYNAMIC_CTRL_SDRAM_MODE: Issue SDRAM MODE command + * + * - EMC_DYNAMIC_CTRL_SDRAM_PALL: Issue SDRAM PALL (precharge all) command + * + * - EMC_DYNAMIC_CTRL_SDRAM_NOP: Issue SRAM NOP (no operation) command + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlSDRAMInit(uint32_t SDRAM_command) +{ + LPC_EMC->DynamicControl &= ~EMC_DYNAMIC_CTRL_SDRAM_INIT_BMASK; + LPC_EMC->DynamicControl |= SDRAM_command & EMC_DYNAMIC_CTRL_SDRAM_INIT_BMASK; + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Switch between Normal operation and deep sleep power mode + * + * @param[in] Power_command Low-power SDRAM deep-sleep mode, should be: + * + * - EMC_DYNAMIC_CTRL_DP_NORMAL: Normal operation + * + * - EMC_DYNAMIC_CTRL_DP_DEEPSLEEP: Enter deep-sleep mode + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynCtrlPowerDownMode(uint32_t Power_command) +{ + LPC_EMC->DynamicControl &= ~EMC_DYNAMIC_CTRL_SDRAM_PWRMODE_BMASK; + LPC_EMC->DynamicControl |= Power_command & EMC_DYNAMIC_CTRL_SDRAM_PWRMODE_BMASK; + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Set the value of EMC dynamic memory registers + * + * @param[in] par EMC register that will set value, should be: + * - EMC_DYN_MEM_REFRESH_TIMER: Dynamic Refresh register + * - EMC_DYN_MEM_READ_CONFIG: Dynamic Read Config register + * - EMC_DYN_MEM_TRP: Dynamic RP register + * - EMC_DYN_MEM_TRAS: Dynamic RAS register + * - EMC_DYN_MEM_TSREX: Dynamic SREX register + * - EMC_DYN_MEM_TAPR: Dynamic APR register + * - EMC_DYN_MEM_TDAL: Dynamic DAL register + * - EMC_DYN_MEM_TWR: Dynamic WR register + * - EMC_DYN_MEM_TRC: Dynamic RC register + * - EMC_DYN_MEM_TRFC: Dynamic RFC register + * - EMC_DYN_MEM_TXSR: Dynamic XSR register + * - EMC_DYN_MEM_TRRD: Dynamic RRD register + * - EMC_DYN_MEM_TMRD: Dynamic MRD register + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_SetDynMemoryParameter(EMC_DYN_MEM_PAR par, uint32_t val) +{ + switch ( par) + { + case EMC_DYN_MEM_REFRESH_TIMER: + LPC_EMC->DynamicRefresh = EMC_DynamicRefresh_REFRESH(val); + break; + + case EMC_DYN_MEM_READ_CONFIG: + LPC_EMC->DynamicReadConfig = EMC_DynamicReadConfig_RD(val); + break; + + case EMC_DYN_MEM_TRP: + LPC_EMC->DynamicRP = EMC_DynamictRP_tRP(val); + break; + + case EMC_DYN_MEM_TRAS: + LPC_EMC->DynamicRAS = EMC_DynamictRP_tRAS(val); + break; + + case EMC_DYN_MEM_TSREX: + LPC_EMC->DynamicSREX = EMC_DynamictRP_tSREX(val); + break; + + case EMC_DYN_MEM_TAPR: + LPC_EMC->DynamicAPR = EMC_DynamictAPR_tAPR(val); + break; + + case EMC_DYN_MEM_TDAL: + LPC_EMC->DynamicDAL =EMC_DynamictDAL_tDAL(val); + break; + + case EMC_DYN_MEM_TWR: + LPC_EMC->DynamicWR = EMC_DynamictWR_tWR(val); + break; + + case EMC_DYN_MEM_TRC: + LPC_EMC->DynamicRC = EMC_DynamictRC_tRC(val); + break; + + case EMC_DYN_MEM_TRFC: + LPC_EMC->DynamicRFC = EMC_DynamictRFC_tRFC(val); + break; + + case EMC_DYN_MEM_TXSR: + LPC_EMC->DynamicXSR = EMC_DynamictXSR_tXSR(val); + break; + + case EMC_DYN_MEM_TRRD: + LPC_EMC->DynamicRRD = EMC_DynamictRRD_tRRD(val); + break; + + case EMC_DYN_MEM_TMRD: + LPC_EMC->DynamicMRD = EMC_DynamictMRD_tMRD(val); + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Configure the memory device + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] mem_dev Memory device, should be: + * + * - EMC_DYNAMIC_CFG_MEMDEV_SDRAM: SDRAM + * + * - EMC_DYNAMIC_CFG_MEMDEV_LOWPWR_SDRAM: Low-power SDRAM + * + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemConfigMD(uint32_t index , uint32_t mem_dev) +{ + switch (index) + { + case 0: + LPC_EMC->DynamicConfig0 &= ~EMC_DYNAMIC_CFG_MEMDEV_BMASK; + LPC_EMC->DynamicConfig0 |= mem_dev & EMC_DYNAMIC_CFG_MEMDEV_BMASK; + break; + + case 1: + LPC_EMC->DynamicConfig1 &= ~EMC_DYNAMIC_CFG_MEMDEV_BMASK; + LPC_EMC->DynamicConfig1 |= mem_dev & EMC_DYNAMIC_CFG_MEMDEV_BMASK; + break; + + case 2: + LPC_EMC->DynamicConfig2 &= ~EMC_DYNAMIC_CFG_MEMDEV_BMASK; + LPC_EMC->DynamicConfig2 |= mem_dev & EMC_DYNAMIC_CFG_MEMDEV_BMASK; + break; + + case 3: + LPC_EMC->DynamicConfig3 &= ~EMC_DYNAMIC_CFG_MEMDEV_BMASK; + LPC_EMC->DynamicConfig3 |= mem_dev & EMC_DYNAMIC_CFG_MEMDEV_BMASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Map the address for the memory device + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] add_mapped address where the memory will be mapped + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemConfigAM(uint32_t index , + uint8_t addr_bus_width, uint8_t addr_map, + uint8_t data_bus_width, + uint16_t chip_size) +{ + const int chip_max_size = 512; // 512Mb + uint8_t data_bus_max_size = 0; + uint32_t add_mapped_p1 = 0x00, add_mapped_p2 = 0x00, add_mapped_p3 = 0x00; + uint32_t tmp = 16, i = 0, j = 0; + + /* Get part 3 of address map */ + switch(addr_bus_width) + { + case 16: + add_mapped_p3 = 0; + data_bus_max_size = 16; + break; + case 32: + add_mapped_p3 = 1; + data_bus_max_size = 32; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + + /* Get part 2 of address map */ + add_mapped_p2 = EMC_DYNAMIC_CFG_ADD_MAP_P2(addr_map); + + + /* Get part 1 of address map */ + if(chip_size == 16) + { + if(data_bus_width == 8) + add_mapped_p1 = 0; + else if(data_bus_width == 16) + add_mapped_p1 = 1; + else + return EMC_FUNC_INVALID_PARAM; + } + else + { + while(1) + { + i++; + tmp = 16*(0x01 << (i+1)); + if(tmp == chip_size) + { + for(j = 0; (8< data_bus_max_size) + return EMC_FUNC_INVALID_PARAM; + + add_mapped_p1 = (i<<2) + j; + break; + } + if(tmp >= chip_max_size) + { + return EMC_FUNC_INVALID_PARAM; + } + } + } + + switch ( index) + { + case 0: + LPC_EMC->DynamicConfig0 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P1_MASK; + LPC_EMC->DynamicConfig0 |= EMC_DYNAMIC_CFG_ADD_MAP_P1(add_mapped_p1); + LPC_EMC->DynamicConfig0 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P2_MASK; + LPC_EMC->DynamicConfig0 |= EMC_DYNAMIC_CFG_ADD_MAP_P2(add_mapped_p2); + LPC_EMC->DynamicConfig0 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P3_MASK; + LPC_EMC->DynamicConfig0 |= EMC_DYNAMIC_CFG_ADD_MAP_P3(add_mapped_p3); + break; + + case 1: + LPC_EMC->DynamicConfig1 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P1_MASK; + LPC_EMC->DynamicConfig1 |= EMC_DYNAMIC_CFG_ADD_MAP_P1(add_mapped_p1); + LPC_EMC->DynamicConfig1 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P2_MASK; + LPC_EMC->DynamicConfig1 |= EMC_DYNAMIC_CFG_ADD_MAP_P2(add_mapped_p2); + LPC_EMC->DynamicConfig1 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P3_MASK; + LPC_EMC->DynamicConfig1 |= EMC_DYNAMIC_CFG_ADD_MAP_P3(add_mapped_p3); + + break; + + case 2: + LPC_EMC->DynamicConfig2 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P1_MASK; + LPC_EMC->DynamicConfig2 |= EMC_DYNAMIC_CFG_ADD_MAP_P1(add_mapped_p1); + LPC_EMC->DynamicConfig2 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P2_MASK; + LPC_EMC->DynamicConfig2 |= EMC_DYNAMIC_CFG_ADD_MAP_P2( add_mapped_p2); + LPC_EMC->DynamicConfig2 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P3_MASK; + LPC_EMC->DynamicConfig2 |= EMC_DYNAMIC_CFG_ADD_MAP_P3(add_mapped_p3); + + break; + + case 3: + LPC_EMC->DynamicConfig3 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P1_MASK; + LPC_EMC->DynamicConfig3 |= EMC_DYNAMIC_CFG_ADD_MAP_P1(add_mapped_p1); + LPC_EMC->DynamicConfig3 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P2_MASK; + LPC_EMC->DynamicConfig3 |= EMC_DYNAMIC_CFG_ADD_MAP_P2(add_mapped_p2); + LPC_EMC->DynamicConfig3 &= ~EMC_DYNAMIC_CFG_ADD_MAP_P3_MASK; + LPC_EMC->DynamicConfig3 |= EMC_DYNAMIC_CFG_ADD_MAP_P3(add_mapped_p3); + + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Enable/disable the buffer + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] buff_control buffer control mode, should be: + * + * - EMC_DYNAMIC_CFG_BUFF_DISABLED: buffer is disabled + * + * - EMC_DYNAMIC_CFG_BUFF_ENABLED: buffer is enable + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemConfigB(uint32_t index , uint32_t buff_control) +{ + switch ( index) + { + case 0: + LPC_EMC->DynamicConfig0 &= ~EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + LPC_EMC->DynamicConfig0 |= buff_control & EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + break; + + case 1: + LPC_EMC->DynamicConfig1 &= ~EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + LPC_EMC->DynamicConfig1 |= buff_control& EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + break; + + case 2: + LPC_EMC->DynamicConfig2 &= ~EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + LPC_EMC->DynamicConfig2 |= buff_control& EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + break; + + case 3: + LPC_EMC->DynamicConfig3 &= ~EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + LPC_EMC->DynamicConfig3|= buff_control& EMC_DYNAMIC_CFG_BUFFENABLE_BMASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Configure write permission: protect or not + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] permission permission mode, should be: + * + * - EMC_DYNAMIC_CFG_WR_UNPROTECTED: will not protect + * + * - EMC_DYNAMIC_CFG_WR_PROTECTED: will protect + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemConfigP(uint32_t index , uint32_t permission) +{ + + switch ( index) + { + case 0: + LPC_EMC->DynamicConfig0 &= ~ EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + LPC_EMC->DynamicConfig0 |= permission&EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + break; + + case 1: + LPC_EMC->DynamicConfig1 &= ~ EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + LPC_EMC->DynamicConfig1 |= permission&EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + break; + + case 2: + LPC_EMC->DynamicConfig2 &= ~ EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + LPC_EMC->DynamicConfig2 |= permission&EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + break; + + case 3: + LPC_EMC->DynamicConfig3 &= ~ EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + LPC_EMC->DynamicConfig3 |= permission&EMC_DYNAMIC_CFG_WRPROTECT_BMASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Set value for RAS latency + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] ras_val RAS value should be in range: 0..3 + * + * @return EMC_FUNC_OK + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemRAS(uint32_t index , uint32_t ras_val) +{ + switch ( index) + { + case 0: + LPC_EMC->DynamicRasCas0 &= ~EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + LPC_EMC->DynamicRasCas0 |=( ras_val << EMC_DYNAMIC_RASCAS_RASCFG_POS) + &EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + break; + + case 1: + LPC_EMC->DynamicRasCas1 &= ~EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + LPC_EMC->DynamicRasCas1 |= ( ras_val << EMC_DYNAMIC_RASCAS_RASCFG_POS) + &EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + break; + + case 2: + LPC_EMC->DynamicRasCas2 &= ~EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + LPC_EMC->DynamicRasCas2 |= ( ras_val << EMC_DYNAMIC_RASCAS_RASCFG_POS) + &EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + break; + + case 3: + LPC_EMC->DynamicRasCas3 &= ~EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + LPC_EMC->DynamicRasCas3 |= ( ras_val << EMC_DYNAMIC_RASCAS_RASCFG_POS) + &EMC_DYNAMIC_RASCAS_RASCFG_BMASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Set value for CAS latency + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] ras_val CAS value should be in range: 0..3 + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_DynMemCAS(uint32_t index , uint32_t cas_val) +{ + switch ( index) + { + case 0: + LPC_EMC->DynamicRasCas0 &= ~EMC_DYNAMIC_RASCAS_CASCFG_BMASK; + LPC_EMC->DynamicRasCas0 |= (cas_val<DynamicRasCas1 &= ~EMC_DYNAMIC_RASCAS_CASCFG_BMASK; + LPC_EMC->DynamicRasCas1 |= (cas_val<DynamicRasCas2 &= ~EMC_DYNAMIC_RASCAS_CASCFG_BMASK; + LPC_EMC->DynamicRasCas2 |= (cas_val<DynamicRasCas3 &= ~EMC_DYNAMIC_RASCAS_CASCFG_BMASK; + LPC_EMC->DynamicRasCas3 |= (cas_val<StaticExtendedWait = EMC_StaticExtendedWait_EXTENDEDWAIT(Extended_wait_time_out); + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Configure the memory width + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] mem_width memory width, should be: + * + * - EMC_STATIC_CFG_MW_8BITS: 8-bits + * + * - EMC_STATIC_CFG_MW_16BITS: 16-bits + * + * - EMC_STATIC_CFG_MW_32BITS02: 32-bits + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigMW(uint32_t index , uint32_t mem_width) +{ + uint32_t mem_width_flg = 0; + switch(mem_width) + { + case 8: + mem_width_flg = EMC_STATIC_CFG_MW_8BITS; + break; + case 16: + mem_width_flg = EMC_STATIC_CFG_MW_16BITS; + break; + case 32: + mem_width_flg = EMC_STATIC_CFG_MW_32BITS; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~ EMC_STATIC_CFG_MEMWIDTH_BMASK; + LPC_EMC->StaticConfig0 |= mem_width_flg; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~ EMC_STATIC_CFG_MEMWIDTH_BMASK; + LPC_EMC->StaticConfig1 |= mem_width_flg; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~ EMC_STATIC_CFG_MEMWIDTH_BMASK; + LPC_EMC->StaticConfig2 |= mem_width_flg; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~ EMC_STATIC_CFG_MEMWIDTH_BMASK; + LPC_EMC->StaticConfig3 |= mem_width_flg; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} +/*********************************************************************//** + * @brief Configure the page mode + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] page_mode page mode, should be: + * + * - EMC_CFG_PM_DISABLE: disable + * + * - EMC_CFG_PM_ASYNC_ENABLE: asynchronous page mode enable + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigPM(uint32_t index , uint32_t page_mode) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_PAGEMODE_MASK; + LPC_EMC->StaticConfig0 |= page_mode&EMC_STATIC_CFG_PAGEMODE_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_PAGEMODE_MASK; + LPC_EMC->StaticConfig1 |= page_mode&EMC_STATIC_CFG_PAGEMODE_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_PAGEMODE_MASK; + LPC_EMC->StaticConfig2 |= page_mode&EMC_STATIC_CFG_PAGEMODE_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_PAGEMODE_MASK; + LPC_EMC->StaticConfig3 |= page_mode&EMC_STATIC_CFG_PAGEMODE_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Configure the chip select polarity + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] pagepol_val_mode page mode, should be: + * + * - EMC_CFG_BYTELAND_PC_ACTIVE_LO: Active LOW ship select + * + * - EMC_CFG_BYTELAND_PC_ACTIVE_HI: Active HIGH chip select + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigPC(uint32_t index , uint32_t pol_val) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_CHIPPOLARITY_MASK; + LPC_EMC->StaticConfig0 |= pol_val&EMC_STATIC_CFG_CHIPPOLARITY_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_CHIPPOLARITY_MASK; + LPC_EMC->StaticConfig1 |= pol_val&EMC_STATIC_CFG_CHIPPOLARITY_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_CHIPPOLARITY_MASK; + LPC_EMC->StaticConfig2 |= pol_val&EMC_STATIC_CFG_CHIPPOLARITY_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_CHIPPOLARITY_MASK; + LPC_EMC->StaticConfig3 |= pol_val&EMC_STATIC_CFG_CHIPPOLARITY_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Configure the byte lane state + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] pb_val Byte lane state, should be: + * + * - EMC_CFG_BYTELAND_READ_BITSHIGH: For reads all bits + * in BLSn[3:0] are HIGH. + * + * - EMC_CFG_BYTELAND_READ_BITSLOW: For reads all bits + * in BLSn[3:0] are LOW. + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigPB(uint32_t index , uint32_t pb_val) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_BYTELAND_MASK; + LPC_EMC->StaticConfig0 |= pb_val&EMC_STATIC_CFG_BYTELAND_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_BYTELAND_MASK; + LPC_EMC->StaticConfig1 |= pb_val&EMC_STATIC_CFG_BYTELAND_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_BYTELAND_MASK; + LPC_EMC->StaticConfig2 |= pb_val&EMC_STATIC_CFG_BYTELAND_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_BYTELAND_MASK; + LPC_EMC->StaticConfig3 |= pb_val&EMC_STATIC_CFG_BYTELAND_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Configure the extended wait value + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] ex_wait Extended wait mode, should be: + * + * - EMC_CFG_EW_DISABLED: Extended wait disabled. + * + * - EMC_CFG_EW_ENABLED: Extended wait enabled. + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigEW(uint32_t index , uint32_t ex_wait) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_EXTWAIT_MASK; + LPC_EMC->StaticConfig0 |= ex_wait&EMC_STATIC_CFG_EXTWAIT_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_EXTWAIT_MASK; + LPC_EMC->StaticConfig1 |= ex_wait&EMC_STATIC_CFG_EXTWAIT_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_EXTWAIT_MASK; + LPC_EMC->StaticConfig2 |= ex_wait&EMC_STATIC_CFG_EXTWAIT_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_EXTWAIT_MASK; + LPC_EMC->StaticConfig3 |= ex_wait&EMC_STATIC_CFG_EXTWAIT_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Configure the buffer enable value + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] buf_val Buffer mode, should be: + * + * - EMC_CFG_BUF_DISABLED: Buffer disabled. + * + * - EMC_CFG_BUF_ENABLED: Buffer enabled. + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigB(uint32_t index , uint32_t buf_val) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_BUFENABLE_MASK; + LPC_EMC->StaticConfig0 |= buf_val&EMC_STATIC_CFG_BUFENABLE_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_BUFENABLE_MASK; + LPC_EMC->StaticConfig1 |= buf_val&EMC_STATIC_CFG_BUFENABLE_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_BUFENABLE_MASK; + LPC_EMC->StaticConfig2 |= buf_val&EMC_STATIC_CFG_BUFENABLE_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_BUFENABLE_MASK; + LPC_EMC->StaticConfig3 |= buf_val&EMC_STATIC_CFG_BUFENABLE_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Configure the write permission + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] per_val Permission mode, should be: + * + * - EMC_CFG_WRITEPROTECT_DISABLED: Write not protected. + * + * - EMC_CFG_WRITEPROTECT_ENABLED: Write protected. + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_StaMemConfigpP(uint32_t index , uint32_t per_val) +{ + switch ( index) + { + case 0: + LPC_EMC->StaticConfig0 &= ~EMC_STATIC_CFG_WRIEPROTECT_MASK; + LPC_EMC->StaticConfig0 |= per_val&EMC_STATIC_CFG_WRIEPROTECT_MASK; + break; + + case 1: + LPC_EMC->StaticConfig1 &= ~EMC_STATIC_CFG_WRIEPROTECT_MASK; + LPC_EMC->StaticConfig1 |= per_val&EMC_STATIC_CFG_WRIEPROTECT_MASK; + break; + + case 2: + LPC_EMC->StaticConfig2 &= ~EMC_STATIC_CFG_WRIEPROTECT_MASK; + LPC_EMC->StaticConfig2 |= per_val&EMC_STATIC_CFG_WRIEPROTECT_MASK; + break; + + case 3: + LPC_EMC->StaticConfig3 &= ~EMC_STATIC_CFG_WRIEPROTECT_MASK; + LPC_EMC->StaticConfig3 |= per_val&EMC_STATIC_CFG_WRIEPROTECT_MASK; + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + return EMC_FUNC_OK; +} + +/*********************************************************************//** + * @brief Set the value of LPC_EMC static memory registers + * + * @param[in] index index number, should be from 0 to 3 + * + * @param[in] EMC_STA_MEM_PAR Static register, should be: + * + * - EMC_STA_MEM_WAITWEN: StaticWaitWen0 register + * - EMC_STA_MEM_WAITOEN: StaticWaitOen0 register + * - EMC_STA_MEM_WAITRD: StaticWaitRd0 register + * - EMC_STA_MEM_WAITPAGE: StaticWaitPage0 register + * - EMC_STA_MEM_WAITWR: StaticWaitWr0 register + * - EMC_STA_MEM_WAITTURN: StaticWaitTurn0 register + * + * @return EMC_FUNC_OK/EMC_FUNC_INVALID_PARAM + **********************************************************************/ +EMC_FUNC_CODE EMC_SetStaMemoryParameter(uint32_t index ,EMC_STA_MEM_PAR par, uint32_t val) +{ + switch (index) + { + case 0: + switch ( par) + { + case EMC_STA_MEM_WAITWEN: + LPC_EMC->StaticWaitWen0 = EMC_StaticWaitWen_WAITWEN(val); + break; + + case EMC_STA_MEM_WAITOEN: + LPC_EMC->StaticWaitOen0 = EMC_StaticWaitOen_WAITOEN(val); + break; + + case EMC_STA_MEM_WAITRD: + LPC_EMC->StaticWaitRd0 = EMC_StaticWaitRd_WAITRD(val); + break; + + case EMC_STA_MEM_WAITPAGE: + LPC_EMC->StaticWaitPage0 = EMC_StaticwaitPage_WAITPAGE(val); + break; + + case EMC_STA_MEM_WAITWR: + LPC_EMC->StaticWaitWr0 = EMC_StaticWaitwr_WAITWR(val); + break; + + case EMC_STA_MEM_WAITTURN: + LPC_EMC->StaticWaitTurn0 =EMC_StaticWaitTurn_WAITTURN(val); + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + break; + + case 1: + switch ( par) + { + case EMC_STA_MEM_WAITWEN: + LPC_EMC->StaticWaitWen1 = EMC_StaticWaitWen_WAITWEN(val); + break; + + case EMC_STA_MEM_WAITOEN: + LPC_EMC->StaticWaitOen1 = EMC_StaticWaitOen_WAITOEN(val); + break; + + case EMC_STA_MEM_WAITRD: + LPC_EMC->StaticWaitRd1 = EMC_StaticWaitRd_WAITRD(val); + break; + + case EMC_STA_MEM_WAITPAGE: + LPC_EMC->StaticWaitPage1 = EMC_StaticwaitPage_WAITPAGE(val); + break; + + case EMC_STA_MEM_WAITWR: + LPC_EMC->StaticWaitWr1 = EMC_StaticWaitwr_WAITWR(val); + break; + + case EMC_STA_MEM_WAITTURN: + LPC_EMC->StaticWaitTurn1 =EMC_StaticWaitTurn_WAITTURN(val); + break; + default: + return EMC_FUNC_INVALID_PARAM; + + } + break; + + case 2: + switch ( par) + { + case EMC_STA_MEM_WAITWEN: + LPC_EMC->StaticWaitWen2 = EMC_StaticWaitWen_WAITWEN(val); + break; + + case EMC_STA_MEM_WAITOEN: + LPC_EMC->StaticWaitOen2 = EMC_StaticWaitOen_WAITOEN(val); + break; + + case EMC_STA_MEM_WAITRD: + LPC_EMC->StaticWaitRd2 = EMC_StaticWaitRd_WAITRD(val); + break; + + case EMC_STA_MEM_WAITPAGE: + LPC_EMC->StaticWaitPage2 = EMC_StaticwaitPage_WAITPAGE(val); + break; + + case EMC_STA_MEM_WAITWR: + LPC_EMC->StaticWaitWr2 = EMC_StaticWaitwr_WAITWR(val); + break; + + case EMC_STA_MEM_WAITTURN: + LPC_EMC->StaticWaitTurn2 =EMC_StaticWaitTurn_WAITTURN(val); + break; + default: + return EMC_FUNC_INVALID_PARAM; + + } + break; + + case 3: + switch ( par) + { + case EMC_STA_MEM_WAITWEN: + LPC_EMC->StaticWaitWen3 = EMC_StaticWaitWen_WAITWEN(val); + break; + + case EMC_STA_MEM_WAITOEN: + LPC_EMC->StaticWaitOen3 = EMC_StaticWaitOen_WAITOEN(val); + break; + + case EMC_STA_MEM_WAITRD: + LPC_EMC->StaticWaitRd3 = EMC_StaticWaitRd_WAITRD(val); + break; + + case EMC_STA_MEM_WAITPAGE: + LPC_EMC->StaticWaitPage3 = EMC_StaticwaitPage_WAITPAGE(val); + break; + + case EMC_STA_MEM_WAITWR: + LPC_EMC->StaticWaitWr3 = EMC_StaticWaitwr_WAITWR(val); + break; + + case EMC_STA_MEM_WAITTURN: + LPC_EMC->StaticWaitTurn3 =EMC_StaticWaitTurn_WAITTURN(val); + break; + default: + return EMC_FUNC_INVALID_PARAM; + } + break; + } + return EMC_FUNC_OK; +} +/** + * @} + */ + + /** + * @} + */ +#endif /*_EMC*/ + + + + + + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_exti.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_exti.c new file mode 100644 index 0000000000000000000000000000000000000000..148267ee8ba92127bf900a01002e28e1df852300 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_exti.c @@ -0,0 +1,162 @@ +/********************************************************************** +* $Id$ lpc_exti.c 2011-06-02 +*//** +* @file lpc_exti.c +* @brief Contains all functions support for External Interrupt +* firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup EXTI + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _EXTI + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_exti.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup EXTI_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Initial for EXT + * - Set EXTINT, EXTMODE, EXTPOLAR registers to default value + * @param[in] None + * @return None + **********************************************************************/ +void EXTI_Init(void) +{ + LPC_SC->EXTINT = 0xF; + LPC_SC->EXTMODE = 0x0; + LPC_SC->EXTPOLAR = 0x0; +} + + +/*********************************************************************//** +* @brief Close EXT +* @param[in] None +* @return None +**********************************************************************/ +void EXTI_DeInit(void) +{ + ; +} + +/*********************************************************************//** + * @brief Configuration for EXT + * - Set EXTINT, EXTMODE, EXTPOLAR register + * @param[in] EXTICfg Pointer to a EXTI_InitTypeDef structure + * that contains the configuration information for the + * specified external interrupt + * @return None + **********************************************************************/ +void EXTI_Config(EXTI_InitTypeDef *EXTICfg) +{ + LPC_SC->EXTINT = 0x0; + EXTI_SetMode(EXTICfg->EXTI_Line, EXTICfg->EXTI_Mode); + EXTI_SetPolarity(EXTICfg->EXTI_Line, EXTICfg->EXTI_polarity); +} + +/*********************************************************************//** +* @brief Set mode for EXTI pin +* @param[in] EXTILine external interrupt line, should be: +* - EXTI_EINT0: external interrupt line 0 +* - EXTI_EINT1: external interrupt line 1 +* - EXTI_EINT2: external interrupt line 2 +* - EXTI_EINT3: external interrupt line 3 +* @param[in] mode external mode, should be: +* - EXTI_MODE_LEVEL_SENSITIVE +* - EXTI_MODE_EDGE_SENSITIVE +* @return None +*********************************************************************/ +void EXTI_SetMode(EXTI_LINE_ENUM EXTILine, EXTI_MODE_ENUM mode) +{ + if(mode == EXTI_MODE_EDGE_SENSITIVE) + { + LPC_SC->EXTMODE |= (1 << EXTILine); + } + else if(mode == EXTI_MODE_LEVEL_SENSITIVE) + { + LPC_SC->EXTMODE &= ~(1 << EXTILine); + } +} + +/*********************************************************************//** +* @brief Set polarity for EXTI pin +* @param[in] EXTILine external interrupt line, should be: +* - EXTI_EINT0: external interrupt line 0 +* - EXTI_EINT1: external interrupt line 1 +* - EXTI_EINT2: external interrupt line 2 +* - EXTI_EINT3: external interrupt line 3 +* @param[in] polarity external polarity value, should be: +* - EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE +* - EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE +* @return None +*********************************************************************/ +void EXTI_SetPolarity(EXTI_LINE_ENUM EXTILine, EXTI_POLARITY_ENUM polarity) +{ + if(polarity == EXTI_POLARITY_HIGH_ACTIVE_OR_RISING_EDGE) + { + LPC_SC->EXTPOLAR |= (1 << EXTILine); + } + else if(polarity == EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE) + { + LPC_SC->EXTPOLAR &= ~(1 << EXTILine); + } +} + +/*********************************************************************//** +* @brief Clear External interrupt flag +* @param[in] EXTILine external interrupt line, should be: +* - EXTI_EINT0: external interrupt line 0 +* - EXTI_EINT1: external interrupt line 1 +* - EXTI_EINT2: external interrupt line 2 +* - EXTI_EINT3: external interrupt line 3 +* @return None +*********************************************************************/ +void EXTI_ClearEXTIFlag(EXTI_LINE_ENUM EXTILine) +{ + LPC_SC->EXTINT |= (1 << EXTILine); +} + +/** + * @} + */ +#endif /*_EXTI*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_gpdma.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_gpdma.c new file mode 100644 index 0000000000000000000000000000000000000000..8e8823d3dddd7eea9e0e1ce46f1a412c8e014c54 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_gpdma.c @@ -0,0 +1,453 @@ +/********************************************************************** +* $Id$ lpc_gpdma.c 2011-06-02 +*//** +* @file lpc_gpdma.c +* @brief Contains all functions support for GPDMA firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup GPDMA + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _GPDMA + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_gpdma.h" +#include "lpc_clkpwr.h" + +/* Private Variables ---------------------------------------------------------- */ +/** @defgroup GPDMA_Private_Variables GPDMA Private Variables + * @{ + */ + +/** + * @brief Lookup Table of Connection Type matched with + * Peripheral Data (FIFO) register base address + */ +volatile const void *GPDMA_LUTPerAddr[] = { + 0, // Revered + (&LPC_MCI->FIFO), // SD Card + (&LPC_SSP0->DR), // SSP0 Tx + (&LPC_SSP0->DR), // SSP0 Rx + (&LPC_SSP1->DR), // SSP1 Tx + (&LPC_SSP1->DR), // SSP1 Rx + (&LPC_SSP2->DR), // SSP2 Tx + (&LPC_SSP2->DR), // SSP2 Rx + (&LPC_ADC->GDR), // ADC + (&LPC_DAC->CR), // DAC + (&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx + (&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx + (&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx + (&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx + (&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx + (&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx + (&LPC_TIM0->MR0), // MAT0.0 + (&LPC_TIM0->MR1), // MAT0.1 + (&LPC_TIM1->MR0), // MAT1.0 + (&LPC_TIM1->MR1), // MAT1.1 + (&LPC_TIM2->MR0), // MAT2.0 + (&LPC_TIM2->MR1), // MAT2.1 + (&LPC_I2S->TXFIFO), // I2S Tx + (&LPC_I2S->RXFIFO), // I2S Rx + 0, // Reverse + 0, // Reverse + (&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx + (&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx + (&LPC_UART4->/*RBTHDLR.*/THR), // UART4 Tx + (&LPC_UART4->/*RBTHDLR.*/RBR), // UART4 Rx + (&LPC_TIM3->MR0), // MAT3.0 + (&LPC_TIM3->MR1), // MAT3.1 +}; + +/** + * @brief Lookup Table of GPDMA Channel Number matched with + * GPDMA channel pointer + */ +const LPC_GPDMACH_TypeDef *pGPDMACh[8] = { + LPC_GPDMACH0, // GPDMA Channel 0 + LPC_GPDMACH1, // GPDMA Channel 1 + LPC_GPDMACH2, // GPDMA Channel 2 + LPC_GPDMACH3, // GPDMA Channel 3 + LPC_GPDMACH4, // GPDMA Channel 4 + LPC_GPDMACH5, // GPDMA Channel 5 + LPC_GPDMACH6, // GPDMA Channel 6 + LPC_GPDMACH7, // GPDMA Channel 7 +}; +/** + * @brief Optimized Peripheral Source and Destination burst size + */ +const uint8_t GPDMA_LUTPerBurst[] = { + 0, // Reserved + GPDMA_BSIZE_8, // SD Card + GPDMA_BSIZE_4, // SSP0 Tx + GPDMA_BSIZE_4, // SSP0 Rx + GPDMA_BSIZE_4, // SSP1 Tx + GPDMA_BSIZE_4, // SSP1 Rx + GPDMA_BSIZE_4, // SSP2 Tx + GPDMA_BSIZE_4, // SSP2 Rx + GPDMA_BSIZE_1, // ADC + GPDMA_BSIZE_1, // DAC + GPDMA_BSIZE_1, // UART0 Tx + GPDMA_BSIZE_1, // UART0 Rx + GPDMA_BSIZE_1, // UART1 Tx + GPDMA_BSIZE_1, // UART1 Rx + GPDMA_BSIZE_1, // UART2 Tx + GPDMA_BSIZE_1, // UART2 Rx + GPDMA_BSIZE_1, // MAT0.0 + GPDMA_BSIZE_1, // MAT0.1 + GPDMA_BSIZE_1, // MAT1.0 + GPDMA_BSIZE_1, // MAT1.1 + GPDMA_BSIZE_1, // MAT2.0 + GPDMA_BSIZE_1, // MAT2.1 + GPDMA_BSIZE_32, // I2S channel 0 + GPDMA_BSIZE_32, // I2S channel 1 + 0, // Reserved + 0, // Reserved + GPDMA_BSIZE_1, // UART3 Tx + GPDMA_BSIZE_1, // UART3 Rx + GPDMA_BSIZE_1, // UART4 Tx + GPDMA_BSIZE_1, // UART4 Rx + GPDMA_BSIZE_1, // MAT3.0 + GPDMA_BSIZE_1, // MAT3.1 +}; +/** + * @brief Optimized Peripheral Source and Destination transfer width + */ +const uint8_t GPDMA_LUTPerWid[] = { + 0, // Reserved + GPDMA_WIDTH_WORD, // SD Card + GPDMA_WIDTH_BYTE, // SSP0 Tx + GPDMA_WIDTH_BYTE, // SSP0 Rx + GPDMA_WIDTH_BYTE, // SSP1 Tx + GPDMA_WIDTH_BYTE, // SSP1 Rx + GPDMA_WIDTH_BYTE, // SSP2 Tx + GPDMA_WIDTH_BYTE, // SSP2 Rx + GPDMA_WIDTH_WORD, // ADC + GPDMA_WIDTH_BYTE, // DAC + GPDMA_WIDTH_BYTE, // UART0 Tx + GPDMA_WIDTH_BYTE, // UART0 Rx + GPDMA_WIDTH_BYTE, // UART1 Tx + GPDMA_WIDTH_BYTE, // UART1 Rx + GPDMA_WIDTH_BYTE, // UART2 Tx + GPDMA_WIDTH_BYTE, // UART2 Rx + GPDMA_WIDTH_WORD, // MAT0.0 + GPDMA_WIDTH_WORD, // MAT0.1 + GPDMA_WIDTH_WORD, // MAT1.0 + GPDMA_WIDTH_WORD, // MAT1.1 + GPDMA_WIDTH_WORD, // MAT2.0 + GPDMA_WIDTH_WORD, // MAT2.1 + GPDMA_WIDTH_WORD, // I2S channel 0 + GPDMA_WIDTH_WORD, // I2S channel 1 + 0, // Reserved + 0, // Reserved + GPDMA_WIDTH_BYTE, // UART3 Tx + GPDMA_WIDTH_BYTE, // UART3 Rx + GPDMA_WIDTH_BYTE, // UART4 Tx + GPDMA_WIDTH_BYTE, // UART4 Rx + GPDMA_WIDTH_WORD, // MAT3.0 + GPDMA_WIDTH_WORD, // MAT3.1 +}; + +/** + * @} + */ + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup GPDMA_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initialize GPDMA controller + * @param None + * @return None + *********************************************************************/ +void GPDMA_Init(void) +{ + /* Enable GPDMA clock */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCGPDMA, ENABLE); + + // Reset all channel configuration register + LPC_GPDMACH0->CConfig = 0; + LPC_GPDMACH1->CConfig = 0; + LPC_GPDMACH2->CConfig = 0; + LPC_GPDMACH3->CConfig = 0; + LPC_GPDMACH4->CConfig = 0; + LPC_GPDMACH5->CConfig = 0; + LPC_GPDMACH6->CConfig = 0; + LPC_GPDMACH7->CConfig = 0; + + /* Clear all DMA interrupt and error flag */ + LPC_GPDMA->IntTCClear = 0xFF; + LPC_GPDMA->IntErrClr = 0xFF; +} + +/********************************************************************//** + * @brief Setup GPDMA channel peripheral according to the specified + * parameters in the GPDMAChannelConfig. + * @param[in] GPDMAChannelConfig Pointer to a GPDMA_CH_CFG_Type + * structure that contains the configuration + * information for the specified GPDMA channel peripheral. + * @return ERROR if selected channel is enabled before + * or SUCCESS if channel is configured successfully + *********************************************************************/ +Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig) +{ + LPC_GPDMACH_TypeDef *pDMAch; + uint32_t tmp1, tmp2; + + if (LPC_GPDMA->EnbldChns & (GPDMA_DMACEnbldChns_Ch(GPDMAChannelConfig->ChannelNum))) { + // This channel is enabled, return ERROR, need to release this channel first + return ERROR; + } + + // Get Channel pointer + pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[GPDMAChannelConfig->ChannelNum]; + + // Reset the Interrupt status + LPC_GPDMA->IntTCClear = GPDMA_DMACIntTCClear_Ch(GPDMAChannelConfig->ChannelNum); + LPC_GPDMA->IntErrClr = GPDMA_DMACIntErrClr_Ch(GPDMAChannelConfig->ChannelNum); + + // Clear DMA configure + pDMAch->CControl = 0x00; + pDMAch->CConfig = 0x00; + + /* Assign Linker List Item value */ + pDMAch->CLLI = GPDMAChannelConfig->DMALLI; + + /* Set value to Channel Control Registers */ + switch (GPDMAChannelConfig->TransferType) + { + // Memory to memory + case GPDMA_TRANSFERTYPE_M2M: + // Assign physical source and destination address + pDMAch->CSrcAddr = GPDMAChannelConfig->SrcMemAddr; + pDMAch->CDestAddr = GPDMAChannelConfig->DstMemAddr; + pDMAch->CControl + = GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize) \ + | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_32) \ + | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_32) \ + | GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth) \ + | GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth) \ + | GPDMA_DMACCxControl_SI \ + | GPDMA_DMACCxControl_DI \ + | GPDMA_DMACCxControl_I; + break; + // Memory to peripheral + case GPDMA_TRANSFERTYPE_M2P: + case GPDMA_TRANSFERTYPE_M2P_DEST_CTRL: + // Assign physical source + pDMAch->CSrcAddr = GPDMAChannelConfig->SrcMemAddr; + // Assign peripheral destination address + pDMAch->CDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn]; + pDMAch->CControl + = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \ + | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_SI \ + | GPDMA_DMACCxControl_I; + break; + // Peripheral to memory + case GPDMA_TRANSFERTYPE_P2M: + case GPDMA_TRANSFERTYPE_P2M_SRC_CTRL: + // Assign peripheral source address + pDMAch->CSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn]; + // Assign memory destination address + pDMAch->CDestAddr = GPDMAChannelConfig->DstMemAddr; + pDMAch->CControl + = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \ + | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_DI \ + | GPDMA_DMACCxControl_I; + break; + // Peripheral to peripheral + case GPDMA_TRANSFERTYPE_P2P: + // Assign peripheral source address + pDMAch->CSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn]; + // Assign peripheral destination address + pDMAch->CDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn]; + pDMAch->CControl = GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \ + | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \ + | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \ + | GPDMA_DMACCxControl_I; + break; + // Do not support any more transfer type, return ERROR + default: + return ERROR; + } + + /* Re-Configure DMA Request Select for source peripheral */ + if((GPDMAChannelConfig->SrcConn != 8)&&(GPDMAChannelConfig->SrcConn != 9)) + { + if (GPDMAChannelConfig->SrcConn > 15) + { + LPC_SC->DMAREQSEL |= (1<<(GPDMAChannelConfig->SrcConn - 16)); + } else { + LPC_SC->DMAREQSEL &= ~(1<<(GPDMAChannelConfig->SrcConn)); + } + } + + /* Re-Configure DMA Request Select for Destination peripheral */ + if((GPDMAChannelConfig->DstConn != 8)&&(GPDMAChannelConfig->DstConn != 9)) + { + if (GPDMAChannelConfig->DstConn > 15) + { + LPC_SC->DMAREQSEL |= (1<<(GPDMAChannelConfig->DstConn - 16)); + } else { + LPC_SC->DMAREQSEL &= ~(1<<(GPDMAChannelConfig->DstConn)); + } + } + + /* Enable DMA channels, little endian */ + LPC_GPDMA->Config = GPDMA_DMACConfig_E; + while (!(LPC_GPDMA->Config & GPDMA_DMACConfig_E)); + + // Calculate absolute value for Connection number + tmp1 = GPDMAChannelConfig->SrcConn; + tmp1 = ((tmp1 > 15) ? (tmp1 - 16) : tmp1); + tmp2 = GPDMAChannelConfig->DstConn; + tmp2 = ((tmp2 > 15) ? (tmp2 - 16) : tmp2); + + // Configure DMA Channel, enable Error Counter and Terminate counter + pDMAch->CConfig = GPDMA_DMACCxConfig_IE | GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/ \ + | GPDMA_DMACCxConfig_TransferType((uint32_t)GPDMAChannelConfig->TransferType) \ + | GPDMA_DMACCxConfig_SrcPeripheral(tmp1) \ + | GPDMA_DMACCxConfig_DestPeripheral(tmp2); + + return SUCCESS; +} + + +/*********************************************************************//** + * @brief Enable/Disable DMA channel + * @param[in] channelNum GPDMA channel, should be in range from 0 to 7 + * @param[in] NewState New State of this command, should be: + * - ENABLE. + * - DISABLE. + * @return None + **********************************************************************/ +void GPDMA_ChannelCmd(uint8_t channelNum, FunctionalState NewState) +{ + LPC_GPDMACH_TypeDef *pDMAch; + + // Get Channel pointer + pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[channelNum]; + + if (NewState == ENABLE) { + pDMAch->CConfig |= GPDMA_DMACCxConfig_E; + } else { + pDMAch->CConfig &= ~GPDMA_DMACCxConfig_E; + } +} +/*********************************************************************//** + * @brief Check if corresponding channel does have an active interrupt + * request or not + * @param[in] type type of status, should be: + * - GPDMA_STAT_INT: GPDMA Interrupt Status + * - GPDMA_STAT_INTTC: GPDMA Interrupt Terminal Count Request Status + * - GPDMA_STAT_INTERR: GPDMA Interrupt Error Status + * - GPDMA_STAT_RAWINTTC: GPDMA Raw Interrupt Terminal Count Status + * - GPDMA_STAT_RAWINTERR: GPDMA Raw Error Interrupt Status + * - GPDMA_STAT_ENABLED_CH:GPDMA Enabled Channel Status + * @param[in] channel GPDMA channel, should be in range from 0 to 7 + * @return IntStatus status of DMA channel interrupt after masking + * Should be: + * - SET: the corresponding channel has no active interrupt request + * - RESET: the corresponding channel does have an active interrupt request + **********************************************************************/ +IntStatus GPDMA_IntGetStatus(GPDMA_Status_Type type, uint8_t channel) +{ + switch (type) + { + case GPDMA_STAT_INT: //check status of DMA channel interrupts + if (LPC_GPDMA->IntStat & (GPDMA_DMACIntStat_Ch(channel))) + return SET; + return RESET; + case GPDMA_STAT_INTTC: // check terminal count interrupt request status for DMA + if (LPC_GPDMA->IntTCStat & GPDMA_DMACIntTCStat_Ch(channel)) + return SET; + return RESET; + case GPDMA_STAT_INTERR: //check interrupt status for DMA channels + if (LPC_GPDMA->IntErrStat & GPDMA_DMACIntTCClear_Ch(channel)) + return SET; + return RESET; + case GPDMA_STAT_RAWINTTC: //check status of the terminal count interrupt for DMA channels + if (LPC_GPDMA->RawIntErrStat & GPDMA_DMACRawIntTCStat_Ch(channel)) + return SET; + return RESET; + case GPDMA_STAT_RAWINTERR: //check status of the error interrupt for DMA channels + if (LPC_GPDMA->RawIntTCStat & GPDMA_DMACRawIntErrStat_Ch(channel)) + return SET; + return RESET; + default: //check enable status for DMA channels + if (LPC_GPDMA->EnbldChns & GPDMA_DMACEnbldChns_Ch(channel)) + return SET; + return RESET; + } +} + +/*********************************************************************//** + * @brief Clear one or more interrupt requests on DMA channels + * @param[in] type type of interrupt request, should be: + * - GPDMA_STATCLR_INTTC: GPDMA Interrupt Terminal Count Request Clear + * - GPDMA_STATCLR_INTERR: GPDMA Interrupt Error Clear + * @param[in] channel GPDMA channel, should be in range from 0 to 7 + * @return None + **********************************************************************/ +void GPDMA_ClearIntPending(GPDMA_StateClear_Type type, uint8_t channel) +{ + if (type == GPDMA_STATCLR_INTTC) // clears the terminal count interrupt request on DMA channel + LPC_GPDMA->IntTCClear = GPDMA_DMACIntTCClear_Ch(channel); + else // clear the error interrupt request + LPC_GPDMA->IntErrClr = GPDMA_DMACIntErrClr_Ch(channel); +} + +/** + * @} + */ + +#endif /* _GPDMA */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_gpio.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..84440f6977998b69ebdfd33a0a6cc0f6e6c23033 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_gpio.c @@ -0,0 +1,905 @@ +/********************************************************************** +* $Id$ lpc_gpio.c 2011-06-02 +*//** +* @file lpc_gpio.c +* @brief Contains all functions support for GPIO firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup GPIO + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _GPIO + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_gpio.h" +#include "lpc_clkpwr.h" + +/* definitions ------------------------------------------------------------------- */ +#define GPIO_IS_ENABLED(x) (((x) != 0)? ENABLE:DISABLE) + +/* Private Functions ---------------------------------------------------------- */ + +static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum); +static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum); +static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum); + +/*********************************************************************//** + * @brief Get pointer to GPIO peripheral due to GPIO port + * @param[in] portNum Port Number value, should be in range from 0 to 4. + * @return Pointer to GPIO peripheral + **********************************************************************/ +static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum) +{ + LPC_GPIO_TypeDef *pGPIO = NULL; + + switch (portNum) + { + case 0: + pGPIO = LPC_GPIO0; + break; + + case 1: + pGPIO = LPC_GPIO1; + break; + + case 2: + pGPIO = LPC_GPIO2; + break; + + case 3: + pGPIO = LPC_GPIO3; + break; + + case 4: + pGPIO = LPC_GPIO4; + break; + + case 5: + pGPIO = LPC_GPIO5; + break; + + default: + break; + } + + return pGPIO; +} + +/*********************************************************************//** + * @brief Get pointer to FIO peripheral in halfword accessible style + * due to FIO port + * @param[in] portNum Port Number value, should be in range from 0 to 4. + * @return Pointer to FIO peripheral + **********************************************************************/ +static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum) +{ + GPIO_HalfWord_TypeDef *pFIO = NULL; + + switch (portNum) + { + case 0: + pFIO = GPIO0_HalfWord; + break; + + case 1: + pFIO = GPIO1_HalfWord; + break; + + case 2: + pFIO = GPIO2_HalfWord; + break; + + case 3: + pFIO = GPIO3_HalfWord; + break; + + case 4: + pFIO = GPIO4_HalfWord; + break; + + case 5: + pFIO = GPIO5_HalfWord; + break; + + default: + break; + } + + return pFIO; +} + +/*********************************************************************//** + * @brief Get pointer to FIO peripheral in byte accessible style + * due to FIO port + * @param[in] portNum Port Number value, should be in range from 0 to 4. + * @return Pointer to FIO peripheral + **********************************************************************/ +static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum) +{ + GPIO_Byte_TypeDef *pFIO = NULL; + + switch (portNum) + { + case 0: + pFIO = GPIO0_Byte; + break; + + case 1: + pFIO = GPIO1_Byte; + break; + + case 2: + pFIO = GPIO2_Byte; + break; + + case 3: + pFIO = GPIO3_Byte; + break; + + case 4: + pFIO = GPIO4_Byte; + break; + + case 5: + pFIO = GPIO5_Byte; + break; + + default: + break; + } + + return pFIO; +} + +/* End of Private Functions --------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup GPIO_Public_Functions + * @{ + */ + + +/* GPIO ------------------------------------------------------------------------------ */ + +/*********************************************************************//** + * @brief Initialize the GPIO component by power on the clock + * supplied to it. + * @return None + * + * Note: + **********************************************************************/ +void GPIO_Init(void) +{ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCGPIO, ENABLE); + + return; +} + + +/*********************************************************************//** + * @brief De-initialize the GPIO component by power off the clock + * supplied to it. + * @return None + * + * Note: + **********************************************************************/ +void GPIO_Deinit(void) +{ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCGPIO, DISABLE); + + return; +} + + +/*********************************************************************//** + * @brief Set Direction for GPIO port. + * @param[in] portNum Port Number value, should be in range from 0 to 4 + * @param[in] bitValue Value that contains all bits to set direction, + * in range from 0 to 0xFFFFFFFF. + * example: value 0x5 to set direction for bit 0 and bit 1. + * @param[in] dir Direction value, should be: + * - 0: Input. + * - 1: Output. + * @return None + * + * Note: All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir) +{ + LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum); + + if (pGPIO != NULL) + { + // Enable Output + if (dir) + { + pGPIO->DIR |= bitValue; + } + // Enable Input + else + { + pGPIO->DIR &= ~bitValue; + } + } +} + + +/*********************************************************************//** + * @brief Set Value for bits that have output direction on GPIO port. + * @param[in] portNum Port number value, should be in range from 0 to 4 + * @param[in] bitValue Value that contains all bits on GPIO to set, + * in range from 0 to 0xFFFFFFFF. + * example: value 0x5 to set bit 0 and bit 1. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void GPIO_SetValue(uint8_t portNum, uint32_t bitValue) +{ + LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum); + + if (pGPIO != NULL) + { + pGPIO->SET = bitValue; + } +} + +/*********************************************************************//** + * @brief Clear Value for bits that have output direction on GPIO port. + * @param[in] portNum Port number value, should be in range from 0 to 4 + * @param[in] bitValue Value that contains all bits on GPIO to clear, + * in range from 0 to 0xFFFFFFFF. + * example: value 0x5 to clear bit 0 and bit 1. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue) +{ + LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum); + + if (pGPIO != NULL) + { + pGPIO->CLR = bitValue; + } +} + +/*********************************************************************//** + * @brief Output to the GPIO pin an expected value + * @param[in] portNum Port number value, should be in range from 0 to 4 + * @param[in] bitValue Value that contains all bits on GPIO to clear, + * in range from 0 to 0xFFFFFFFF. + * example: value 0x5 to clear bit 0 and bit 1. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void GPIO_OutputValue(uint8_t portNum, uint32_t bitMask, uint8_t value) +{ + if (value == 0) + { + GPIO_ClearValue(portNum, bitMask); + } + else + { + GPIO_SetValue(portNum, bitMask); + } + +} + + +/*********************************************************************//** + * @brief Read Current state on port pin that have input direction of GPIO + * @param[in] portNum Port number to read value, in range from 0 to 4 + * @return Current value of GPIO port. + * + * Note: Return value contain state of each port pin (bit) on that GPIO regardless + * its direction is input or output. + **********************************************************************/ +uint32_t GPIO_ReadValue(uint8_t portNum) +{ + LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum); + + if (pGPIO != NULL) + { + return pGPIO->PIN; + } + + return (0); +} + +/*********************************************************************//** + * @brief Enable GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13) + * @param[in] portNum Port number to read value, should be: 0 or 2 + * @param[in] bitValue Value that contains all bits on GPIO to enable, + * in range from 0 to 0xFFFFFFFF. + * @param[in] edgeState state of edge, should be: + * - 0: Rising edge + * - 1: Falling edge + * @return None + **********************************************************************/ +void GPIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState) +{ + if((portNum == 0)&&(edgeState == 0)) + LPC_GPIOINT->IO0IntEnR = bitValue; + else if ((portNum == 2)&&(edgeState == 0)) + LPC_GPIOINT->IO2IntEnR = bitValue; + else if ((portNum == 0)&&(edgeState == 1)) + LPC_GPIOINT->IO0IntEnF = bitValue; + else if ((portNum == 2)&&(edgeState == 1)) + LPC_GPIOINT->IO2IntEnF = bitValue; + else + //Error + while(1); +} + +/*********************************************************************//** + * @brief Get GPIO Interrupt Status (just used for P0.0-P0.30, P2.0-P2.13) + * @param[in] portNum Port number to read value, should be: 0 or 2 + * @param[in] pinNum Pin number, should be: 0..30(with port 0) and 0..13 + * (with port 2) + * @param[in] edgeState state of edge, should be: + * - 0: Rising edge + * - 1: Falling edge + * @return Bool could be: + * - ENABLE: Interrupt has been generated due to a rising + * edge on P0.0 + * - DISABLE: A rising edge has not been detected on P0.0 + **********************************************************************/ +FunctionalState GPIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState) +{ + if((portNum == 0) && (edgeState == 0))//Rising Edge + return GPIO_IS_ENABLED(((LPC_GPIOINT->IO0IntStatR)>>pinNum)& 0x1); + else if ((portNum == 2) && (edgeState == 0)) + return GPIO_IS_ENABLED(((LPC_GPIOINT->IO2IntStatR)>>pinNum)& 0x1); + else if ((portNum == 0) && (edgeState == 1))//Falling Edge + return GPIO_IS_ENABLED(((LPC_GPIOINT->IO0IntStatF)>>pinNum)& 0x1); + else if ((portNum == 2) && (edgeState == 1)) + return GPIO_IS_ENABLED(((LPC_GPIOINT->IO2IntStatF)>>pinNum)& 0x1); + else + //Error + while(1); +} +/*********************************************************************//** + * @brief Clear GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13) + * @param[in] portNum Port number to read value, should be: 0 or 2 + * @param[in] bitValue Value that contains all bits on GPIO to enable, + * in range from 0 to 0xFFFFFFFF. + * @return None + **********************************************************************/ +void GPIO_ClearInt(uint8_t portNum, uint32_t bitValue) +{ + if(portNum == 0) + LPC_GPIOINT->IO0IntClr = bitValue; + else if (portNum == 2) + LPC_GPIOINT->IO2IntClr = bitValue; + else + //Invalid portNum + while(1); +} + +/* FIO word accessible ----------------------------------------------------------------- */ +/* Stub function for FIO (word-accessible) style */ + +/** + * @brief The same with GPIO_SetDir() + */ +void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir) +{ + GPIO_SetDir(portNum, bitValue, dir); +} + +/** + * @brief The same with GPIO_SetValue() + */ +void FIO_SetValue(uint8_t portNum, uint32_t bitValue) +{ + GPIO_SetValue(portNum, bitValue); +} + +/** + * @brief The same with GPIO_ClearValue() + */ +void FIO_ClearValue(uint8_t portNum, uint32_t bitValue) +{ + GPIO_ClearValue(portNum, bitValue); +} + +/** + * @brief The same with GPIO_ReadValue() + */ +uint32_t FIO_ReadValue(uint8_t portNum) +{ + return (GPIO_ReadValue(portNum)); +} + +/** + * @brief The same with GPIO_IntCmd() + */ +void FIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState) +{ + GPIO_IntCmd(portNum, bitValue, edgeState); +} + +/** + * @brief The same with GPIO_GetIntStatus() + */ +FunctionalState FIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState) +{ + return (GPIO_GetIntStatus(portNum, pinNum, edgeState)); +} + +/** + * @brief The same with GPIO_ClearInt() + */ +void FIO_ClearInt(uint8_t portNum, uint32_t bitValue) +{ + GPIO_ClearInt(portNum, bitValue); +} +/*********************************************************************//** + * @brief Set mask value for bits in FIO port + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] bitValue Value that contains all bits in to set, + * in range from 0 to 0xFFFFFFFF. + * @param[in] maskValue Mask value contains state value for each bit: + * - 0: not mask. + * - 1: mask. + * @return None + * + * Note: + * - All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + * - After executing this function, in mask register, value '0' on each bit + * enables an access to the corresponding physical pin via a read or write access, + * while value '1' on bit (masked) that corresponding pin will not be changed + * with write access and if read, will not be reflected in the updated pin. + **********************************************************************/ +void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue) +{ + LPC_GPIO_TypeDef *pFIO = GPIO_GetPointer(portNum); + + if(pFIO != NULL) + { + // Mask + if (maskValue) + { + pFIO->MASK |= bitValue; + } + // Un-mask + else + { + pFIO->MASK &= ~bitValue; + } + } +} + + +/* FIO halfword accessible ------------------------------------------------------------- */ + +/*********************************************************************//** + * @brief Set direction for FIO port in halfword accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper) + * @param[in] bitValue Value that contains all bits in to set direction, + * in range from 0 to 0xFFFF. + * @param[in] dir Direction value, should be: + * - 0: Input. + * - 1: Output. + * @return None + * + * Note: All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir) +{ + GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum); + + if(pFIO != NULL) + { + // Output direction + if (dir) + { + // Upper + if(halfwordNum) + { + pFIO->FIODIRU |= bitValue; + } + // lower + else + { + pFIO->FIODIRL |= bitValue; + } + } + // Input direction + else + { + // Upper + if(halfwordNum) + { + pFIO->FIODIRU &= ~bitValue; + } + // lower + else + { + pFIO->FIODIRL &= ~bitValue; + } + } + } +} + + +/*********************************************************************//** + * @brief Set mask value for bits in FIO port in halfword accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper) + * @param[in] bitValue Value that contains all bits in to set, + * in range from 0 to 0xFFFF. + * @param[in] maskValue Mask value contains state value for each bit: + * - 0: not mask. + * - 1: mask. + * @return None + * + * Note: + * - All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + * - After executing this function, in mask register, value '0' on each bit + * enables an access to the corresponding physical pin via a read or write access, + * while value '1' on bit (masked) that corresponding pin will not be changed + * with write access and if read, will not be reflected in the updated pin. + **********************************************************************/ +void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue) +{ + GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum); + + if(pFIO != NULL) + { + // Mask + if (maskValue) + { + // Upper + if(halfwordNum) + { + pFIO->FIOMASKU |= bitValue; + } + // lower + else + { + pFIO->FIOMASKL |= bitValue; + } + } + // Un-mask + else + { + // Upper + if(halfwordNum) + { + pFIO->FIOMASKU &= ~bitValue; + } + // lower + else + { + pFIO->FIOMASKL &= ~bitValue; + } + } + } +} + + +/*********************************************************************//** + * @brief Set bits for FIO port in halfword accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper) + * @param[in] bitValue Value that contains all bits in to set, + * in range from 0 to 0xFFFF. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue) +{ + GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum); + + if(pFIO != NULL) + { + // Upper + if(halfwordNum) + { + pFIO->FIOSETU = bitValue; + } + // lower + else + { + pFIO->FIOSETL = bitValue; + } + } +} + + +/*********************************************************************//** + * @brief Clear bits for FIO port in halfword accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper) + * @param[in] bitValue Value that contains all bits in to clear, + * in range from 0 to 0xFFFF. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue) +{ + GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum); + + if(pFIO != NULL) + { + // Upper + if(halfwordNum) + { + pFIO->FIOCLRU = bitValue; + } + // lower + else + { + pFIO->FIOCLRL = bitValue; + } + } +} + + +/*********************************************************************//** + * @brief Read Current state on port pin that have input direction of GPIO + * in halfword accessible style. + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper) + * @return Current value of FIO port pin of specified halfword. + * Note: Return value contain state of each port pin (bit) on that FIO regardless + * its direction is input or output. + **********************************************************************/ +uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum) +{ + GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum); + + if(pFIO != NULL) + { + // Upper + if(halfwordNum) + { + return (pFIO->FIOPINU); + } + // lower + else + { + return (pFIO->FIOPINL); + } + } + + return (0); +} + + +/* FIO Byte accessible ------------------------------------------------------------ */ + +/*********************************************************************//** + * @brief Set direction for FIO port in byte accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] byteNum Byte part number, should be in range from 0 to 3 + * @param[in] bitValue Value that contains all bits in to set direction, + * in range from 0 to 0xFF. + * @param[in] dir Direction value, should be: + * - 0: Input. + * - 1: Output. + * @return None + * + * Note: All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir) +{ + GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum); + + if(pFIO != NULL) + { + // Output direction + if (dir) + { + if (byteNum <= 3) + { + pFIO->FIODIR[byteNum] |= bitValue; + } + } + // Input direction + else + { + if (byteNum <= 3) + { + pFIO->FIODIR[byteNum] &= ~bitValue; + } + } + } +} + +/*********************************************************************//** + * @brief Set mask value for bits in FIO port in byte accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] byteNum Byte part number, should be in range from 0 to 3 + * @param[in] bitValue Value that contains all bits in to set mask, + * in range from 0 to 0xFF. + * @param[in] maskValue Mask value contains state value for each bit: + * - 0: not mask. + * - 1: mask. + * @return None + * + * Note: + * - All remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + * - After executing this function, in mask register, value '0' on each bit + * enables an access to the corresponding physical pin via a read or write access, + * while value '1' on bit (masked) that corresponding pin will not be changed + * with write access and if read, will not be reflected in the updated pin. + **********************************************************************/ +void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue) +{ + GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum); + + if(pFIO != NULL) + { + // Mask + if (maskValue) + { + if (byteNum <= 3) + { + pFIO->FIOMASK[byteNum] |= bitValue; + } + } + // Un-mask + else { + if (byteNum <= 3) + { + pFIO->FIOMASK[byteNum] &= ~bitValue; + } + } + } +} + + +/*********************************************************************//** + * @brief Set bits for FIO port in byte accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] byteNum Byte part number, should be in range from 0 to 3 + * @param[in] bitValue Value that contains all bits in to set, + * in range from 0 to 0xFF. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue) +{ + GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum); + + if (pFIO != NULL) { + if (byteNum <= 3) + { + pFIO->FIOSET[byteNum] = bitValue; + } + } +} + + +/*********************************************************************//** + * @brief Clear bits for FIO port in byte accessible style + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] byteNum Byte part number, should be in range from 0 to 3 + * @param[in] bitValue Value that contains all bits in to clear, + * in range from 0 to 0xFF. + * @return None + * + * Note: + * - For all bits that has been set as input direction, this function will + * not effect. + * - For all remaining bits that are not activated in bitValue (value '0') + * will not be effected by this function. + **********************************************************************/ +void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue) +{ + GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum); + + if (pFIO != NULL) + { + if (byteNum <= 3) + { + pFIO->FIOCLR[byteNum] = bitValue; + } + } +} + + +/*********************************************************************//** + * @brief Read Current state on port pin that have input direction of GPIO + * in byte accessible style. + * @param[in] portNum Port number, in range from 0 to 4 + * @param[in] byteNum Byte part number, should be in range from 0 to 3 + * @return Current value of FIO port pin of specified byte part. + * Note: Return value contain state of each port pin (bit) on that FIO regardless + * its direction is input or output. + **********************************************************************/ +uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum) +{ + GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum); + + if (pFIO != NULL) + { + if (byteNum <= 3) + { + return (pFIO->FIOPIN[byteNum]); + } + } + return (0); +} + +/** + * @} + */ + +#endif /* _GPIO */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_i2c.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..c466cf655e452b997dec1b910b058783c175545f --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_i2c.c @@ -0,0 +1,1416 @@ +/********************************************************************** +* $Id$ lpc_i2c.c 2011-06-02 +*//** +* @file lpc_i2c.c +* @brief Contains all functions support for I2C firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup I2C + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _I2C + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_i2c.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +/* Private Types -------------------------------------------------------------- */ +/** @defgroup I2C_Private_Types I2C Private Types + * @{ + */ + +/** + * @brief I2C device configuration structure type + */ +typedef struct +{ + uint32_t txrx_setup; /* Transmission setup */ + int32_t dir; /* Current direction phase, 0 - write, 1 - read */ +} I2C_CFG_T; + +/** + * @} + */ + +/* Private Variables ---------------------------------------------------------- */ +/** + * @brief II2C driver data for I2C0, I2C1 and I2C2 + */ +static I2C_CFG_T i2cdat[3]; + +static uint32_t I2C_MasterComplete[3]; +static uint32_t I2C_SlaveComplete[3]; + +static uint32_t I2C_MonitorBufferIndex; + +/* Private Functions ---------------------------------------------------------- */ + +/* Get pointer to expected I2C */ +static LPC_I2C_TypeDef* I2C_GetPointer(en_I2C_unitId compId); + +/* Generate a start condition on I2C bus (in master mode only) */ +static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx, I2C_TRANSFER_OPT_Type Opt); + +/* Generate a stop condition on I2C bus (in master mode only) */ +static void I2C_Stop (LPC_I2C_TypeDef *I2Cx, I2C_TRANSFER_OPT_Type Opt); + +/* I2C send byte subroutine */ +static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte); + +/* I2C get byte subroutine */ +static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack); + +/* I2C set clock (hz) */ +static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock); + +/*--------------------------------------------------------------------------------*/ + +/********************************************************************//** + * @brief Convert from I2C peripheral to number + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return I2C number, could be: 0..2 + *********************************************************************/ +static LPC_I2C_TypeDef* I2C_GetPointer(en_I2C_unitId compId) +{ + LPC_I2C_TypeDef* pI2C; + + switch (compId) + { + case I2C_0: + pI2C = LPC_I2C0; + break; + + case I2C_1: + pI2C = LPC_I2C1; + break; + + case I2C_2: + pI2C = LPC_I2C2; + break; + + default: + pI2C = NULL; + break; + } + + return pI2C; +} + + +/********************************************************************//** + * @brief Generate a start condition on I2C bus (in master mode only) + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return value of I2C status register after generate a start condition + *********************************************************************/ +static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx, I2C_TRANSFER_OPT_Type Opt) +{ + // Reset STA, STO, SI + I2Cx->CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC; + + // Enter to Master Transmitter mode + I2Cx->CONSET = I2C_I2CONSET_STA; + + if(Opt == I2C_TRANSFER_POLLING) + { + // Wait for complete + while (!(I2Cx->CONSET & I2C_I2CONSET_SI)); + } + + return (I2Cx->STAT & I2C_STAT_CODE_BITMASK); +} + +/********************************************************************//** + * @brief Generate a stop condition on I2C bus (in master mode only) + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return None + *********************************************************************/ +static void I2C_Stop (LPC_I2C_TypeDef *I2Cx, I2C_TRANSFER_OPT_Type Opt) +{ + /* Make sure start bit is not active */ + if (I2Cx->CONSET & I2C_I2CONSET_STA) + { + I2Cx->CONCLR = I2C_I2CONCLR_STAC; + } + + I2Cx->CONSET = I2C_I2CONSET_STO; + + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + + if(Opt == I2C_TRANSFER_POLLING) + { + // wait for stop is sent + while(I2Cx->CONSET & I2C_I2CONSET_STO) + { + if(I2Cx->CONSET & I2C_I2CONSET_SI) + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + } + } +} + +/********************************************************************//** + * @brief Send a byte + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] databyte: number of byte + * @return value of I2C status register after sending + *********************************************************************/ +static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte) +{ + uint32_t CodeStatus = I2Cx->STAT & I2C_STAT_CODE_BITMASK; + + if((CodeStatus != I2C_I2STAT_M_TX_START) && + (CodeStatus != I2C_I2STAT_M_TX_RESTART) && + (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK) && + (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK) ) + { + return CodeStatus; + } + + I2Cx->DAT = databyte & I2C_I2DAT_BITMASK; + + I2Cx->CONSET = I2C_I2CONSET_AA; + + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + + return (I2Cx->STAT & I2C_STAT_CODE_BITMASK); +} + +/********************************************************************//** + * @brief Get a byte + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[out] retdat pointer to return data + * @param[in] ack assert acknowledge or not, should be: TRUE/FALSE + * @return value of I2C status register after sending + *********************************************************************/ +static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack) +{ + *retdat = (uint8_t) (I2Cx->DAT & I2C_I2DAT_BITMASK); + + if (ack == TRUE) + { + I2Cx->CONSET = I2C_I2CONSET_AA; + } + else + { + I2Cx->CONCLR = I2C_I2CONCLR_AAC; + } + + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + + return (I2Cx->STAT & I2C_STAT_CODE_BITMASK); +} + +/*********************************************************************//** + * @brief Setup clock rate for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] target_clock : clock of SSP (Hz) + * @return None + ***********************************************************************/ +static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) +{ + uint32_t temp; + + temp = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / target_clock; + + /* Set the I2C clock value to register */ + I2Cx->SCLH = (uint32_t)(temp / 2); + + I2Cx->SCLL = (uint32_t)(temp - I2Cx->SCLH); +} + + +/* End of Private Functions --------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup I2C_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initializes the I2Cx peripheral with specified parameter. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] clockrate Target clock rate value to initialized I2C + * peripheral (Hz) + * @return None + *********************************************************************/ +void I2C_Init(en_I2C_unitId i2cId, uint32_t clockrate) +{ + uint32_t clkSetting; + + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + switch (i2cId) + { + case I2C_0: + clkSetting = CLKPWR_PCONP_PCI2C0; + break; + + + case I2C_1: + clkSetting = CLKPWR_PCONP_PCI2C1; + break; + + case I2C_2: + clkSetting = CLKPWR_PCONP_PCI2C2; + break; + + default: + + return; + } + + CLKPWR_ConfigPPWR (clkSetting, ENABLE); + + /* Set clock rate */ + I2C_SetClock(I2Cx,clockrate); + + /* Set I2C operation to default */ + I2Cx->CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); +} + +/*********************************************************************//** + * @brief De-initializes the I2C peripheral registers to their + * default reset values. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_DeInit(en_I2C_unitId i2cId) +{ + uint32_t clkSetting; + + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + /* Disable I2C control */ + I2Cx->CONCLR = 0xFF; + + switch (i2cId) + { + case I2C_0: + clkSetting = CLKPWR_PCONP_PCI2C0; + break; + + + case I2C_1: + clkSetting = CLKPWR_PCONP_PCI2C1; + break; + + case I2C_2: + clkSetting = CLKPWR_PCONP_PCI2C2; + break; + + default: + + return; + } + + CLKPWR_ConfigPPWR (clkSetting, DISABLE); +} + +/*********************************************************************//** + * @brief Enable or disable I2C peripheral's operation + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of I2Cx peripheral's operation + * @return none + **********************************************************************/ +void I2C_Cmd(en_I2C_unitId i2cId, en_I2C_Mode Mode, FunctionalState NewState) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + if (NewState == ENABLE) + { + if(Mode != I2C_SLAVE_MODE) + I2Cx->CONSET = I2C_I2CONSET_I2EN; + else + I2Cx->CONSET = I2C_I2CONSET_I2EN | I2C_I2CONSET_AA; + } + else + { + I2Cx->CONCLR = I2C_I2CONCLR_I2ENC; + } +} + +/*********************************************************************//** + * @brief Enable/Disable interrupt for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of I2C peripheral interrupt in NVIC core + * should be: + * - ENABLE: enable interrupt for this I2C peripheral + * - DISABLE: disable interrupt for this I2C peripheral + * @return None + **********************************************************************/ +void I2C_IntCmd (en_I2C_unitId i2cId, Bool NewState) +{ + IRQn_Type irq; + + switch (i2cId) + { + case I2C_0: + irq = I2C0_IRQn; + break; + + case I2C_1: + irq = I2C1_IRQn; + break; + + case I2C_2: + irq = I2C2_IRQn; + break; + + default: + + return; + } + + if (NewState) + { + NVIC_EnableIRQ(irq); + } + else + { + NVIC_DisableIRQ(irq); + } + + return; +} +/*********************************************************************//** + * @brief Handle I2C Master states. + * @param[in] I2Cx I2C peripheral selected, should be: + * - I2C_0 + * - I2C_1 + * - I2C_2 + * @param[in] CodeStatus I2C state + * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return It can be + * - I2C_OK + * -I2C_BYTE_RECV + * -I2C_BYTE_SENT + * -I2C_SEND_END + * -I2C_RECV_END + * - I2C_ERR + * - I2C_NAK_RECV + **********************************************************************/ +int32_t I2C_MasterHanleStates(en_I2C_unitId i2cId, + uint32_t CodeStatus, + I2C_M_SETUP_Type *TransferCfg, + I2C_TRANSFER_OPT_Type Opt + ) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + uint8_t *txdat; + uint8_t *rxdat; + uint8_t tmp; + int32_t Ret = I2C_OK; + + //get buffer to send/receive + txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count]; + rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count]; + + switch(CodeStatus) + { + case I2C_I2STAT_M_TX_START: + case I2C_I2STAT_M_TX_RESTART: + //case I2C_I2STAT_M_RX_START: + //case I2C_I2STAT_M_RX_RESTART + // Send data first + if(TransferCfg->tx_count < TransferCfg->tx_length) + { + /* Send slave address + WR direction bit = 0 ----------------------------------- */ + I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); + Ret = I2C_BYTE_SENT; + } + else if (TransferCfg->rx_count < TransferCfg->rx_length) + { + /* Send slave address + RD direction bit = 1 ----------------------------------- */ + I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); + Ret = I2C_BYTE_SENT; + } + // Clear STA bit after the slave address is sent + I2Cx->CONCLR = I2C_I2CONCLR_STAC; + break; + case I2C_I2STAT_M_TX_SLAW_ACK: + case I2C_I2STAT_M_TX_DAT_ACK: + + if(TransferCfg->tx_count < TransferCfg->tx_length) + { + I2C_SendByte(I2Cx, *txdat); + + txdat++; + + TransferCfg->tx_count++; + + Ret = I2C_BYTE_SENT; + } + else + { + if(TransferCfg->rx_count >= TransferCfg->rx_length) + { + I2C_Stop(I2Cx, Opt); + } + Ret = I2C_SEND_END; + + + } + + break; + case I2C_I2STAT_M_TX_DAT_NACK: + if(TransferCfg->rx_count >= TransferCfg->rx_length) + { + I2C_Stop(I2Cx, Opt); + } + Ret = I2C_SEND_END; + break; + case I2C_I2STAT_M_RX_ARB_LOST: + case I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL: + case I2C_I2STAT_S_TX_ARB_LOST_M_SLA: + //case I2C_I2STAT_M_TX_ARB_LOST: + I2C_Stop(I2Cx, Opt); + Ret = I2C_ERR; + break; + case I2C_I2STAT_M_RX_SLAR_ACK: + if(TransferCfg->rx_length > 1) + I2Cx->CONSET = I2C_I2CONSET_AA; + else + I2Cx->CONCLR = I2C_I2CONCLR_AAC; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + + Ret = I2C_BYTE_RECV; + break; + case I2C_I2STAT_M_RX_DAT_ACK: + if (TransferCfg->rx_count rx_length) + { + if ((TransferCfg->rx_length > 1) && (TransferCfg->rx_count < (TransferCfg->rx_length - 2))) + { + I2C_GetByte(I2Cx, &tmp, TRUE); + + Ret = I2C_BYTE_RECV; + + } + else // the next byte is the last byte, send NACK instead. + { + I2C_GetByte(I2Cx, &tmp, FALSE); + Ret = I2C_BYTE_RECV; + } + *rxdat++ = tmp; + + TransferCfg->rx_count++; + } + else + { + I2C_Stop(I2Cx, Opt); + Ret = I2C_RECV_END; + } + + break; + case I2C_I2STAT_M_RX_DAT_NACK: + I2C_GetByte(I2Cx, &tmp, FALSE); + if (TransferCfg->rx_count < TransferCfg->rx_length) + { + *rxdat++ = tmp; + TransferCfg->rx_count++; + } + I2C_Stop(I2Cx, Opt); + Ret = I2C_RECV_END; + break; + + case I2C_I2STAT_M_RX_SLAR_NACK: + case I2C_I2STAT_M_TX_SLAW_NACK: + case I2C_I2STAT_BUS_ERROR: + // Send STOP condition + I2C_Stop(I2Cx, Opt); + Ret = I2C_ERR; + break; + /* No status information */ + case I2C_I2STAT_NO_INF: + if ((TransferCfg->tx_count tx_length)|| + (TransferCfg->rx_count rx_length)) + { + I2C_Stop(I2Cx, Opt); + Ret = I2C_ERR; + } + else + { + Ret = I2C_RECV_END; + } + break; + default: + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + } + + return Ret; +} + +/*********************************************************************//** + * @brief Handle I2C Slave states. + * @param[in] I2Cx I2C peripheral selected, should be: + * - I2C_0 + * - I2C_1 + * - I2C_2 + * @param[in] CodeStatus I2C state + * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @return It can be + * - I2C_OK + * -I2C_BYTE_RECV + * -I2C_BYTE_SENT + * -I2C_SEND_END + * -I2C_RECV_END + * - I2C_ERR + * - I2C_NAK_RECV + **********************************************************************/ +int32_t I2C_SlaveHanleStates(en_I2C_unitId i2cId, + uint32_t CodeStatus, + I2C_S_SETUP_Type *TransferCfg) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + int32_t Ret = I2C_OK; + uint8_t *txdat; + uint8_t *rxdat; + + //get buffer to send/receive + txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count]; + rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count]; + + switch (CodeStatus) + { + /* Reading phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_SLAW_ACK: + + /* General call address has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_GENCALL_ACK: + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + /* Arbitration has been lost in Slave Address + R/W bit as bus Master. General Call has + been received and ACK has been returned.*/ + case I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL: + I2Cx->CONSET = I2C_I2CONSET_AA|I2C_I2CONSET_STA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + /* Previously addressed with own SLA; + * DATA byte has been received; + * ACK has been returned */ + case I2C_I2STAT_S_RX_ARB_LOST_M_SLA: + case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: + + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((TransferCfg->rx_count < TransferCfg->rx_length) && (TransferCfg->rx_data != NULL)) + { + *rxdat++ = (uint8_t)I2Cx->DAT; + + TransferCfg->rx_count++; + + Ret = I2C_BYTE_RECV; + } + if(TransferCfg->rx_count == (TransferCfg->rx_length) ) { + I2Cx->CONCLR = I2C_I2CONCLR_AAC|I2C_I2CONCLR_SIC; + Ret = I2C_BYTE_RECV; + } + else { + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + } + + break; + /* DATA has been received, Only the first data byte will be received with ACK. Additional + data will be received with NOT ACK. */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: + if ((TransferCfg->rx_count < TransferCfg->rx_length) && (TransferCfg->rx_data != NULL)) + { + *rxdat++ = (uint8_t)I2Cx->DAT; + + TransferCfg->rx_count++; + + Ret = I2C_BYTE_RECV; + } + I2Cx->CONCLR = I2C_I2CONCLR_AAC|I2C_I2CONCLR_SIC; + break; + + /* Writing phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_TX_SLAR_ACK: + + /* Data has been transmitted, ACK has been received */ + case I2C_I2STAT_S_TX_DAT_ACK: + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((TransferCfg->tx_count < TransferCfg->tx_length) && (TransferCfg->tx_data != NULL)) + { + I2Cx->DAT = *txdat++; + + TransferCfg->tx_count++; + + Ret = I2C_BYTE_SENT; + } + + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + /* Arbitration lost in Slave Address and R/W bit as bus Master. Own Slave Address + Read + has been received, ACK has been returned. */ + case I2C_I2STAT_S_TX_ARB_LOST_M_SLA: + if ((TransferCfg->tx_count < TransferCfg->tx_length) && (TransferCfg->tx_data != NULL)) + { + I2Cx->DAT = *txdat++; + + TransferCfg->tx_count++; + + Ret = I2C_BYTE_SENT; + } + I2Cx->CONSET = I2C_I2CONSET_AA|I2C_I2CONSET_STA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + + case I2C_I2STAT_S_TX_LAST_DAT_ACK: + /* Data has been transmitted, NACK has been received, + * that means there's no more data to send, exit now */ + /* + * Note: Don't wait for stop event since in slave transmit mode, + * since there no proof lets us know when a stop signal has been received + * on slave side. + */ + case I2C_I2STAT_S_TX_DAT_NACK: + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + Ret = I2C_SEND_END; + break; + + /* Previously addressed with own SLA; + * DATA byte has been received; + * NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: + + /* DATA has been received, NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + Ret = I2C_RECV_END; + break; + + /* + * Note that: Return code only let us know a stop condition mixed + * with a repeat start condition in the same code value. + * So we should provide a time-out. In case this is really a stop + * condition, this will return back after time out condition. Otherwise, + * next session that is slave receive data will be completed. + */ + + /* A Stop or a repeat start condition */ + case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + Ret = I2C_STA_STO_RECV; + break; + + /* No status information */ + case I2C_I2STAT_NO_INF: + /* Other status must be captured */ + default: + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + break; + + } + + return Ret; +} +/*********************************************************************//** + * @brief General Master Interrupt handler for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_MasterHandler(en_I2C_unitId i2cId) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + uint8_t returnCode; + I2C_M_SETUP_Type *txrx_setup; + int32_t Ret = I2C_OK; + + txrx_setup = (I2C_M_SETUP_Type *) i2cdat[i2cId].txrx_setup; + + returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK); + + // Save current status + txrx_setup->status = returnCode; + + Ret = I2C_MasterHanleStates(i2cId, returnCode, txrx_setup, I2C_TRANSFER_INTERRUPT); + + if(I2C_CheckError(Ret)) + { + if(txrx_setup->retransmissions_count < txrx_setup->retransmissions_max) + { + // Retry + txrx_setup->retransmissions_count ++; + txrx_setup->tx_count = 0; + txrx_setup->rx_count = 0; + // Reset STA, STO, SI + I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT); + return; + } + else + { + goto s_int_end; + } + } + else if (Ret & I2C_SEND_END) + { + // If no need to wait for data from Slave + if(txrx_setup->rx_count >= (txrx_setup->rx_length)) + { + goto s_int_end; + } + else // Start to wait for data from Slave + { + // Reset STA, STO, SI + I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT); + return; + } + } + else if (Ret & I2C_RECV_END) + { + goto s_int_end; + } + else + { + return; + } + +s_int_end: + // Disable interrupt + I2C_IntCmd(i2cId, FALSE); + + I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + + I2C_MasterComplete[i2cId] = TRUE; + +} + + +/*********************************************************************//** + * @brief General Slave Interrupt handler for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_SlaveHandler (en_I2C_unitId i2cId) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + uint8_t returnCode; + I2C_S_SETUP_Type *txrx_setup; + uint32_t timeout; + int32_t Ret = I2C_OK; + + txrx_setup = (I2C_S_SETUP_Type *) i2cdat[i2cId].txrx_setup; + +handle_state: + + returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK); + // Save current status + txrx_setup->status = returnCode; + + + Ret = I2C_SlaveHanleStates(i2cId, returnCode, txrx_setup); + + if(I2C_CheckError(Ret)) + { + goto s_int_end; + } + else if (Ret & I2C_STA_STO_RECV) + { + if((txrx_setup->tx_count >= (txrx_setup->tx_length)) && + (txrx_setup->rx_count >= (txrx_setup->rx_length))) + { + goto s_int_end; + } + // Temporally lock the interrupt for timeout condition + I2C_IntCmd(i2cId, FALSE); + // enable time out + timeout = I2C_SLAVE_TIME_OUT; + while(1) + { + if (I2Cx->CONSET & I2C_I2CONSET_SI) + { + // re-Enable interrupt + I2C_IntCmd(i2cId, TRUE); + goto handle_state; + } + else + { + timeout--; + if (timeout == 0) + { + // timeout occur, it's really a stop condition + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto s_int_end; + } + } + } + } + else if(Ret &I2C_SEND_END) + { + goto s_int_end; + } + else + { + return; + } + +s_int_end: + // Disable interrupt + I2C_IntCmd(i2cId, FALSE); + I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + + I2C_SlaveComplete[i2cId] = TRUE; +} + +/*********************************************************************//** + * @brief Transmit and Receive data in master mode + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return SUCCESS or ERROR + * + * Note: + * - In case of using I2C to transmit data only, either transmit length set to 0 + * or transmit data pointer set to NULL. + * - In case of using I2C to receive data only, either receive length set to 0 + * or receive data pointer set to NULL. + * - In case of using I2C to transmit followed by receive data, transmit length, + * transmit data pointer, receive length and receive data pointer should be set + * corresponding. + **********************************************************************/ +Status I2C_MasterTransferData(en_I2C_unitId i2cId, I2C_M_SETUP_Type *TransferCfg, + I2C_TRANSFER_OPT_Type Opt) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + uint32_t CodeStatus; + int32_t Ret = I2C_OK; + + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + TransferCfg->status = 0; + + if (Opt == I2C_TRANSFER_POLLING) + { + /* First Start condition -------------------------------------------------------------- */ + TransferCfg->retransmissions_count = 0; +retry: + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + + // Start command + CodeStatus = I2C_Start(I2Cx, I2C_TRANSFER_POLLING); + + while(1) // send data first and then receive data from Slave. + { + Ret = I2C_MasterHanleStates(i2cId, CodeStatus, TransferCfg, I2C_TRANSFER_POLLING); + if(I2C_CheckError(Ret)) + { + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // save status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; + goto error; + } else { + goto retry; + } + } + else if( (Ret & I2C_BYTE_SENT) || + (Ret & I2C_BYTE_RECV)) + { + // Wait for sending ends/ Wait for next byte + while (!(I2Cx->CONSET & I2C_I2CONSET_SI)); + } + else if (Ret & I2C_SEND_END) // already send all data + { + // If no need to wait for data from Slave + if(TransferCfg->rx_count >= (TransferCfg->rx_length)) + { + break; + } + else + { + I2C_Start(I2Cx, I2C_TRANSFER_POLLING); + } + } + else if (Ret & I2C_RECV_END) // already receive all data + { + break; + } + CodeStatus = I2Cx->STAT & I2C_STAT_CODE_BITMASK; + } + return SUCCESS; +error: + return ERROR; + } + + else if (Opt == I2C_TRANSFER_INTERRUPT) + { + // Setup tx_rx data, callback and interrupt handler + i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg; + + // Set direction phase, write first + i2cdat[i2cId].dir = 0; + + /* First Start condition -------------------------------------------------------------- */ + // Reset STA, STO, SI + I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT); + + I2C_IntCmd(i2cId, TRUE); + + return (SUCCESS); + } + + return ERROR; +} + +/*********************************************************************//** + * @brief Receive and Transmit data in slave mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return SUCCESS or ERROR + * + * Note: + * The mode of slave's operation depends on the command sent from master on + * the I2C bus. If the master send a SLA+W command, this sub-routine will + * use receive data length and receive data pointer. If the master send a SLA+R + * command, this sub-routine will use transmit data length and transmit data + * pointer. + * If the master issue an repeat start command or a stop command, the slave will + * enable an time out condition, during time out condition, if there's no activity + * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W), + * the slave then switch to relevant operation mode. The time out should be used + * because the return status code can not show difference from stop and repeat + * start command in slave operation. + * In case of the expected data length from master is greater than data length + * that slave can support: + * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR + * value. + * - In case of writing operation (from master): slave will ignore remain data from master. + **********************************************************************/ +Status I2C_SlaveTransferData(en_I2C_unitId i2cId, I2C_S_SETUP_Type *TransferCfg, + I2C_TRANSFER_OPT_Type Opt) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + int32_t Ret = I2C_OK; + + uint32_t CodeStatus; + uint32_t timeout; + int32_t time_en; + + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + TransferCfg->status = 0; + + // Polling option + if (Opt == I2C_TRANSFER_POLLING) + { + /* Set AA bit to ACK command on I2C bus */ + I2Cx->CONSET = I2C_I2CONSET_AA; + + /* Clear SI bit to be ready ... */ + I2Cx->CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC|I2C_I2CONCLR_STOC); + + time_en = 0; + timeout = 0; + + while (1) + { + /* Check SI flag ready */ + if (I2Cx->CONSET & I2C_I2CONSET_SI) + { + time_en = 0; + + CodeStatus = (I2Cx->STAT & I2C_STAT_CODE_BITMASK); + + Ret = I2C_SlaveHanleStates(i2cId, CodeStatus, TransferCfg); + if(I2C_CheckError(Ret)) + { + goto s_error; + } + else if(Ret & I2C_STA_STO_RECV) + { + if((TransferCfg->tx_count >= (TransferCfg->tx_length)) && + (TransferCfg->rx_count >= (TransferCfg->rx_length))) + { + goto s_end_stage; + } + time_en = 1; + timeout = 0; + } + else if (Ret & I2C_SEND_END) + { + goto s_end_stage; + } + } + else if (time_en) + { + if (timeout++ > I2C_SLAVE_TIME_OUT) + { + // it's really a stop condition, goto end stage + goto s_end_stage; + } + } + } + +s_end_stage: + /* Clear AA bit to disable ACK on I2C bus */ + I2Cx->CONCLR = I2C_I2CONCLR_AAC; + + // Check if there's no error during operation + // Update status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE; + return SUCCESS; + +s_error: + /* Clear AA bit to disable ACK on I2C bus */ + I2Cx->CONCLR = I2C_I2CONCLR_AAC; + + // Update status + TransferCfg->status = CodeStatus; + return ERROR; + } + + else if (Opt == I2C_TRANSFER_INTERRUPT) + { + // Setup tx_rx data, callback and interrupt handler + i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg; + + // Set direction phase, read first + i2cdat[i2cId].dir = 1; + + // Enable AA + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + I2C_IntCmd(i2cId, TRUE); + + return (SUCCESS); + } + + return ERROR; +} + +/*********************************************************************//** + * @brief Set Own slave address in I2C peripheral corresponding to + * parameter specified in OwnSlaveAddrConfigStruct. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type + * structure that contains the configuration information for the +* specified I2C slave address. + * @return None + **********************************************************************/ +void I2C_SetOwnSlaveAddr(en_I2C_unitId i2cId, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + uint32_t tmp; + + tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ + | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; + + switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) + { + case 0: + I2Cx->ADR0 = tmp; + + I2Cx->MASK0 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + + case 1: + I2Cx->ADR1 = tmp; + + I2Cx->MASK1 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + + case 2: + I2Cx->ADR2 = tmp; + + I2Cx->MASK2 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + + case 3: + I2Cx->ADR3 = tmp; + + I2Cx->MASK3 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + } +} + + +/*********************************************************************//** + * @brief Configures functionality in I2C monitor mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] Monitor configuration. It can include: + * - I2C_I2MMCTRL_ENA_SCL: I2C module can 'stretch' + * the clock line (hold it low) until it has had time to + * respond to an I2C interrupt. + * - I2C_I2MMCTRL_MATCH_ALL: When the I2C is in monitor mode, + * an interrupt will be generated on ANY address received. + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return None + **********************************************************************/ +void I2C_MonitorModeConfig(en_I2C_unitId i2cId, uint32_t MonitorCfgType, FunctionalState NewState) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + if (NewState == ENABLE) + { + I2Cx->MMCTRL |= MonitorCfgType; + } + else + { + I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Enable/Disable I2C monitor mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable monitor mode. + * - DISABLE: Disable monitor mode. + * @return None + **********************************************************************/ +void I2C_MonitorModeCmd(en_I2C_unitId i2cId, FunctionalState NewState) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + if (NewState == ENABLE) + { + I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; + I2Cx->CONSET = I2C_I2CONSET_AA; + I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + } + else + { + I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; + I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_AAC; + } + + I2C_MonitorBufferIndex = 0; +} + + +/*********************************************************************//** + * @brief Get data from I2C data buffer in monitor mode. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + * Note: In monitor mode, the I2C module may lose the ability to stretch + * the clock (stall the bus) if the ENA_SCL bit is not set. This means that + * the processor will have a limited amount of time to read the contents of + * the data received on the bus. If the processor reads the DAT shift + * register, as it ordinarily would, it could have only one bit-time to + * respond to the interrupt before the received data is overwritten by + * new data. + **********************************************************************/ +uint8_t I2C_MonitorGetDatabuffer(en_I2C_unitId i2cId) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + return ((uint8_t)(I2Cx->DATA_BUFFER)); +} + +/*********************************************************************//** + * @brief Get data from I2C data buffer in monitor mode. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + * Note: In monitor mode, the I2C module may lose the ability to stretch + * the clock (stall the bus) if the ENA_SCL bit is not set. This means that + * the processor will have a limited amount of time to read the contents of + * the data received on the bus. If the processor reads the DAT shift + * register, as it ordinarily would, it could have only one bit-time to + * respond to the interrupt before the received data is overwritten by + * new data. + **********************************************************************/ +BOOL_8 I2C_MonitorHandler(en_I2C_unitId i2cId, uint8_t *buffer, uint32_t size) +{ + LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); + + BOOL_8 ret=FALSE; + + I2Cx->CONCLR = I2C_I2CONCLR_SIC; + + buffer[I2C_MonitorBufferIndex] = (uint8_t)(I2Cx->DATA_BUFFER); + + I2C_MonitorBufferIndex++; + + if(I2C_MonitorBufferIndex >= size) + { + ret = TRUE; + } + return ret; +} +/*********************************************************************//** + * @brief Get status of Master Transfer + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return Master transfer status, could be: + * - TRUE master transfer completed + * - FALSE master transfer have not completed yet + **********************************************************************/ +uint32_t I2C_MasterTransferComplete(en_I2C_unitId i2cId) +{ + uint32_t retval; + + retval = I2C_MasterComplete[i2cId]; + + I2C_MasterComplete[i2cId] = FALSE; + + return retval; +} + +/*********************************************************************//** + * @brief Get status of Slave Transfer + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return Complete status, could be: TRUE/FALSE + **********************************************************************/ +uint32_t I2C_SlaveTransferComplete(en_I2C_unitId i2cId) +{ + uint32_t retval; + + retval = I2C_SlaveComplete[i2cId]; + + I2C_SlaveComplete[i2cId] = FALSE; + + return retval; +} + +#endif /*_I2C*/ + +/** + * @} + */ + + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_i2s.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_i2s.c new file mode 100644 index 0000000000000000000000000000000000000000..88172c7554138f2953bbd23b93fcf12aad28689e --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_i2s.c @@ -0,0 +1,589 @@ +/********************************************************************** +* $Id$ lpc_i2s.c 2011-06-02 +*//** +* @file lpc_i2s.c +* @brief Contains all functions support for I2S firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup I2S + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _I2S + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_i2s.h" +#include "lpc_clkpwr.h" + +/* definitions ---------------------------------------------------------- */ +#define I2S_IS_ENABLED(x) ((x)? ENABLE:DISABLE) +/* Private Functions ---------------------------------------------------------- */ + +static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); +static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); + +/********************************************************************//** + * @brief Get I2S wordwidth value + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is the I2S mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return The wordwidth value, should be: 8,16 or 32 + *********************************************************************/ +static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { + uint8_t value; + + if (TRMode == I2S_TX_MODE) { + value = (I2Sx->DAO) & 0x03; /* get wordwidth bit */ + } else { + value = (I2Sx->DAI) & 0x03; /* get wordwidth bit */ + } + switch (value) { + case I2S_WORDWIDTH_8: + return 8; + case I2S_WORDWIDTH_16: + return 16; + default: + return 32; + } +} + +/********************************************************************//** + * @brief Get I2S channel value + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is the I2S mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return The channel value, should be: 1(mono) or 2(stereo) + *********************************************************************/ +static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { + uint8_t value; + + if (TRMode == I2S_TX_MODE) { + value = ((I2Sx->DAO) & 0x04)>>2; /* get bit[2] */ + } else { + value = ((I2Sx->DAI) & 0x04)>>2; /* get bit[2] */ + } + if(value == I2S_MONO) return 1; + return 2; +} + +/* End of Private Functions --------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup I2S_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initialize I2S + * - Turn on power and clock + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @return none + *********************************************************************/ +void I2S_Init(LPC_I2S_TypeDef *I2Sx) { + // Turn on power and clock + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, ENABLE); + LPC_I2S->DAI = LPC_I2S->DAO = 0x00; +} + +/********************************************************************//** + * @brief Configuration I2S, setting: + * - master/slave mode + * - wordwidth value + * - channel mode + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @param[in] ConfigStruct pointer to I2S_CFG_Type structure + * which will be initialized. + * @return none + *********************************************************************/ +void I2S_Config(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct) +{ + uint32_t bps, config; + /* Setup clock */ + bps = (ConfigStruct->wordwidth +1)*8; + + /* Calculate audio config */ + config = (bps - 1)<<6 | (ConfigStruct->ws_sel)<<5 | (ConfigStruct->reset)<<4 | + (ConfigStruct->stop)<<3 | (ConfigStruct->mono)<<2 | (ConfigStruct->wordwidth); + + if(TRMode == I2S_RX_MODE){ + LPC_I2S->DAI = config; + }else{ + LPC_I2S->DAO = config; + } +} + +/********************************************************************//** + * @brief DeInitial both I2S transmit or receive + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @return none + *********************************************************************/ +void I2S_DeInit(LPC_I2S_TypeDef *I2Sx) { + // Turn off power and clock + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, DISABLE); +} + +/********************************************************************//** + * @brief Get I2S Buffer Level + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode Transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return current level of Transmit/Receive Buffer + *********************************************************************/ +uint8_t I2S_GetLevel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) +{ + + if(TRMode == I2S_TX_MODE) + { + return ((I2Sx->STATE >> 16) & 0xFF); + } + else + { + return ((I2Sx->STATE >> 8) & 0xFF); + } +} + +/********************************************************************//** + * @brief I2S Start: clear all STOP,RESET and MUTE bit, ready to operate + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @return none + *********************************************************************/ +void I2S_Start(LPC_I2S_TypeDef *I2Sx) +{ + //Clear STOP,RESET and MUTE bit + I2Sx->DAO &= ~I2S_DAI_RESET; + I2Sx->DAI &= ~I2S_DAI_RESET; + I2Sx->DAO &= ~I2S_DAI_STOP; + I2Sx->DAI &= ~I2S_DAI_STOP; + I2Sx->DAO &= ~I2S_DAI_MUTE; +} + +/********************************************************************//** + * @brief I2S Send data + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] BufferData pointer to uint32_t is the data will be send + * @return none + *********************************************************************/ +void I2S_Send(LPC_I2S_TypeDef *I2Sx, uint32_t BufferData) +{ + I2Sx->TXFIFO = BufferData; +} + +/********************************************************************//** + * @brief I2S Receive Data + * @param[in] I2Sx pointer to LPC_I2S_TypeDef + * @return received value + *********************************************************************/ +uint32_t I2S_Receive(LPC_I2S_TypeDef* I2Sx) +{ + return (I2Sx->RXFIFO); +} + +/********************************************************************//** + * @brief I2S Pause + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_Pause(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { + if (TRMode == I2S_TX_MODE) //Transmit mode + { + I2Sx->DAO |= I2S_DAO_STOP; + } else //Receive mode + { + I2Sx->DAI |= I2S_DAI_STOP; + } +} + +/********************************************************************//** + * @brief I2S Mute + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_Mute(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { + if (TRMode == I2S_TX_MODE) //Transmit mode + { + I2Sx->DAO |= I2S_DAO_MUTE; + } else //Receive mode + { + I2Sx->DAI |= I2S_DAI_MUTE; + } +} + +/********************************************************************//** + * @brief I2S Stop + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_Stop(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { + if (TRMode == I2S_TX_MODE) //Transmit mode + { + I2Sx->DAO &= ~I2S_DAO_MUTE; + I2Sx->DAO |= I2S_DAO_STOP; + I2Sx->DAO |= I2S_DAO_RESET; + } else //Receive mode + { + I2Sx->DAI |= I2S_DAI_STOP; + I2Sx->DAI |= I2S_DAI_RESET; + } +} +/********************************************************************//** + * @brief Set frequency for I2S + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] Freq is the frequency for I2S will be set. It can range + * from 16-96 kHz(16, 22.05, 32, 44.1, 48, 96kHz) + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return Status: ERROR or SUCCESS + *********************************************************************/ +Status I2S_FreqConfig(LPC_I2S_TypeDef *I2Sx, uint32_t Freq, uint8_t TRMode) { + uint32_t cclk; + uint8_t channel, wordwidth; + uint32_t x, y; + uint64_t divider; + uint16_t dif; + uint16_t x_divide, y_divide; + uint16_t err, ErrorOptimal = 0xFFFF; + + uint32_t N; + + //get cclk + cclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU); + + if(TRMode == I2S_TX_MODE) + { + channel = i2s_GetChannel(I2Sx,I2S_TX_MODE); + wordwidth = i2s_GetWordWidth(I2Sx,I2S_TX_MODE); + } + else + { + channel = i2s_GetChannel(I2Sx,I2S_RX_MODE); + wordwidth = i2s_GetWordWidth(I2Sx,I2S_RX_MODE); + } + + /* Calculate X and Y divider + * The MCLK rate for the I2S transmitter is determined by the value + * in the I2STXRATE/I2SRXRATE register. The required I2STXRATE/I2SRXRATE + * setting depends on the desired audio sample rate desired, the format + * (stereo/mono) used, and the data size. + * The formula is: + * I2S_MCLK = CCLK * (X/Y) / 2 + * We have: + * I2S_MCLK = Freq * channel*wordwidth * (I2Sx->TXBITRATE+1); + * So: (X/Y) = (Freq * channel*wordwidth * (I2Sx->TXBITRATE+1))/CCLK*2 + * We use a loop function to chose the most suitable X,Y value + */ + + /* divider is a fixed point number with 16 fractional bits */ + divider = (((uint64_t)Freq *channel*wordwidth * 2)<<16) / cclk; + + /* find N that make x/y <= 1 -> divider <= 2^16 */ + for(N=64;N>0;N--){ + if((divider*N) < (1<<16)) break; + } + + if(N == 0) return ERROR; + + divider *= N; + + for (y = 255; y > 0; y--) { + x = y * divider; + if(x & (0xFF000000)) continue; + dif = x & 0xFFFF; + if(dif>0x8000) err = 0x10000-dif; + else err = dif; + if (err == 0) + { + y_divide = y; + break; + } + else if (err < ErrorOptimal) + { + ErrorOptimal = err; + y_divide = y; + } + } + x_divide = ((uint64_t)y_divide * Freq *(channel*wordwidth)* N * 2)/cclk; + if(x_divide >= 256) x_divide = 0xFF; + if(x_divide == 0) x_divide = 1; + + if (TRMode == I2S_TX_MODE)// Transmitter + { + I2Sx->TXBITRATE = N-1; + I2Sx->TXRATE = y_divide | (x_divide << 8); + } else //Receiver + { + I2Sx->RXBITRATE = N-1; + I2Sx->TXRATE = y_divide | (x_divide << 8); + } + return SUCCESS; +} + +/********************************************************************//** + * @brief I2S set bitrate + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] bitrate value will be set + * bitrate value should be in range: 0 .. 63 + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_SetBitRate(LPC_I2S_TypeDef *I2Sx, uint8_t bitrate, uint8_t TRMode) +{ + if(TRMode == I2S_TX_MODE) + { + I2Sx->TXBITRATE = bitrate; + } + else + { + I2Sx->RXBITRATE = bitrate; + } +} + +/********************************************************************//** + * @brief Configuration operating mode for I2S + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] ModeConfig pointer to I2S_MODEConf_Type will be used to + * configure + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_ModeConfig(LPC_I2S_TypeDef *I2Sx, I2S_MODEConf_Type* ModeConfig, + uint8_t TRMode) +{ + if (TRMode == I2S_TX_MODE) { + I2Sx->TXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register + if (ModeConfig->clksel == I2S_CLKSEL_MCLK) { + I2Sx->TXMODE |= 0x02; + } + if (ModeConfig->fpin == I2S_4PIN_ENABLE) { + I2Sx->TXMODE |= (1 << 2); + } + if (ModeConfig->mcena == I2S_MCLK_ENABLE) { + I2Sx->TXMODE |= (1 << 3); + } + } else { + I2Sx->RXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register + if (ModeConfig->clksel == I2S_CLKSEL_MCLK) { + I2Sx->RXMODE |= 0x02; + } + if (ModeConfig->fpin == I2S_4PIN_ENABLE) { + I2Sx->RXMODE |= (1 << 2); + } + if (ModeConfig->mcena == I2S_MCLK_ENABLE) { + I2Sx->RXMODE |= (1 << 3); + } + } +} + +/********************************************************************//** + * @brief Configure DMA operation for I2S + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] DMAConfig pointer to I2S_DMAConf_Type will be used to configure + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return none + *********************************************************************/ +void I2S_DMAConfig(LPC_I2S_TypeDef *I2Sx, I2S_DMAConf_Type* DMAConfig, + uint8_t TRMode) +{ + if (TRMode == I2S_RX_MODE) { + if (DMAConfig->DMAIndex == I2S_DMA_1) { + LPC_I2S->DMA1 = (DMAConfig->depth) << 8; + } else { + LPC_I2S->DMA2 = (DMAConfig->depth) << 8; + } + } else { + if (DMAConfig->DMAIndex == I2S_DMA_1) { + LPC_I2S->DMA1 = (DMAConfig->depth) << 16; + } else { + LPC_I2S->DMA2 = (DMAConfig->depth) << 16; + } + } +} + +/********************************************************************//** + * @brief Enable/Disable DMA operation for I2S + * @param[in] I2Sx: I2S peripheral selected, should be: LPC_I2S + * @param[in] DMAIndex chose what DMA is used, should be: + * - I2S_DMA_1 = 0: DMA1 + * - I2S_DMA_2 = 1: DMA2 + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @param[in] NewState is new state of DMA operation, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void I2S_DMACmd(LPC_I2S_TypeDef *I2Sx, uint8_t DMAIndex, uint8_t TRMode, + FunctionalState NewState) +{ + if (TRMode == I2S_RX_MODE) { + if (DMAIndex == I2S_DMA_1) { + if (NewState == ENABLE) + I2Sx->DMA1 |= 0x01; + else + I2Sx->DMA1 &= ~0x01; + } else { + if (NewState == ENABLE) + I2Sx->DMA2 |= 0x01; + else + I2Sx->DMA2 &= ~0x01; + } + } else { + if (DMAIndex == I2S_DMA_1) { + if (NewState == ENABLE) + I2Sx->DMA1 |= 0x02; + else + I2Sx->DMA1 &= ~0x02; + } else { + if (NewState == ENABLE) + I2Sx->DMA2 |= 0x02; + else + I2Sx->DMA2 &= ~0x02; + } + } +} + +/********************************************************************//** + * @brief Configure IRQ for I2S + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @param[in] level is the FIFO level that triggers IRQ request + * @return none + *********************************************************************/ +void I2S_IRQConfig(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, uint8_t level) { + if (TRMode == I2S_RX_MODE) { + I2Sx->IRQ |= (level << 8); + } else { + I2Sx->IRQ |= (level << 16); + } +} + +/********************************************************************//** + * @brief Enable/Disable IRQ for I2S + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @param[in] NewState is new state of DMA operation, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void I2S_IRQCmd(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, FunctionalState NewState) { + + if (TRMode == I2S_RX_MODE) { + if (NewState == ENABLE) + I2Sx->IRQ |= 0x01; + else + I2Sx->IRQ &= ~0x01; + //Enable DMA + + } else { + if (NewState == ENABLE) + I2Sx->IRQ |= 0x02; + else + I2Sx->IRQ &= ~0x02; + } +} + +/********************************************************************//** + * @brief Get I2S interrupt status + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return FunctionState should be: + * - ENABLE: interrupt is enable + * - DISABLE: interrupt is disable + *********************************************************************/ +FunctionalState I2S_GetIRQStatus(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode) +{ + + if(TRMode == I2S_TX_MODE) + return I2S_IS_ENABLED((I2Sx->IRQ >> 1)&0x01); + else + return I2S_IS_ENABLED((I2Sx->IRQ)&0x01); +} + +/********************************************************************//** + * @brief Get I2S interrupt depth + * @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S + * @param[in] TRMode is transmit/receive mode, should be: + * - I2S_TX_MODE = 0: transmit mode + * - I2S_RX_MODE = 1: receive mode + * @return depth of FIFO level on which to create an irq request + *********************************************************************/ +uint8_t I2S_GetIRQDepth(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode) +{ + + if(TRMode == I2S_TX_MODE) + return (((I2Sx->IRQ)>>16)&0xFF); + else + return (((I2Sx->IRQ)>>8)&0xFF); +} +/** + * @} + */ + +#endif /*_I2S*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_iap.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_iap.c new file mode 100644 index 0000000000000000000000000000000000000000..ceccf3657048a016808a3d491fac9b33abe31d43 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_iap.c @@ -0,0 +1,317 @@ +/********************************************************************** +* $Id$ lpc_iap.c 2011-11-21 +*//** +* @file lpc_iap.c + * @brief Contains all functions support for IAP on LPC +* @version 1.0 +* @date 21. November. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _IAP +#include "lpc_iap.h" +#include "lpc_clkpwr.h" + +// IAP Command +typedef void (*IAP)(uint32_t *cmd,uint32_t *result); +IAP iap_entry = (IAP) IAP_LOCATION; +#define IAP_Call iap_entry + +/** @addtogroup IAP_Public_Functions LCD Public Function + * @ingroup IAP + * @{ + */ + + +/*********************************************************************//** + * @brief Get Sector Number + * + * @param[in] adr Sector Address + * + * @return Sector Number. + * + **********************************************************************/ + uint32_t GetSecNum (uint32_t adr) +{ + uint32_t n; + + n = adr >> 12; // 4kB Sector + if (n >= 0x10) { + n = 0x0E + (n >> 3); // 32kB Sector + } + + return (n); // Sector Number +} + +/*********************************************************************//** + * @brief Prepare sector(s) for write operation + * + * @param[in] start_sec The number of start sector + * @param[in] end_sec The number of end sector + * + * @return CMD_SUCCESS/BUSY/INVALID_SECTOR. + * + **********************************************************************/ +IAP_STATUS_CODE PrepareSector(uint32_t start_sec, uint32_t end_sec) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_PREPARE; // Prepare Sector for Write + command.param[0] = start_sec; // Start Sector + command.param[1] = end_sec; // End Sector + IAP_Call (&command.cmd, &command.status); // Call IAP Command + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Copy RAM to Flash + * + * @param[in] dest destination buffer (in Flash memory). + * @param[in] source source buffer (in RAM). + * @param[in] size the write size. + * + * @return CMD_SUCCESS. + * SRC_ADDR_ERROR/DST_ADDR_ERROR + * SRC_ADDR_NOT_MAPPED/DST_ADDR_NOT_MAPPED + * COUNT_ERROR/SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION + * BUSY + * + **********************************************************************/ +IAP_STATUS_CODE CopyRAM2Flash(uint8_t * dest, uint8_t* source, IAP_WRITE_SIZE size) +{ + uint32_t sec; + IAP_STATUS_CODE status; + IAP_COMMAND_Type command; + + // Prepare sectors + sec = GetSecNum((uint32_t)dest); + status = PrepareSector(sec, sec); + if(status != CMD_SUCCESS) + return status; + + // write + command.cmd = IAP_COPY_RAM2FLASH; // Copy RAM to Flash + command.param[0] = (uint32_t)dest; // Destination Flash Address + command.param[1] = (uint32_t)source; // Source RAM Address + command.param[2] = size; // Number of bytes + command.param[3] = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / 1000; // CCLK in kHz + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + return (IAP_STATUS_CODE)command.status; // Finished without Errors +} + +/*********************************************************************//** + * @brief Erase sector(s) + * + * @param[in] start_sec The number of start sector + * @param[in] end_sec The number of end sector + * + * @return CMD_SUCCESS. + * INVALID_SECTOR + * SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION + * BUSY + * + **********************************************************************/ +IAP_STATUS_CODE EraseSector(uint32_t start_sec, uint32_t end_sec) +{ + IAP_COMMAND_Type command; + IAP_STATUS_CODE status; + + // Prepare sectors + status = PrepareSector(start_sec, end_sec); + if(status != CMD_SUCCESS) + return status; + + // Erase sectors + command.cmd = IAP_ERASE; // Prepare Sector for Write + command.param[0] = start_sec; // Start Sector + command.param[1] = end_sec; // End Sector + command.param[2] = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / 1000; // CCLK in kHz + IAP_Call (&command.cmd, &command.status); // Call IAP Command + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Blank check sector(s) + * + * @param[in] start_sec The number of start sector + * @param[in] end_sec The number of end sector + * @param[out] first_nblank_loc The offset of the first non-blank word + * @param[out] first_nblank_val The value of the first non-blank word + * + * @return CMD_SUCCESS. + * INVALID_SECTOR + * SECTOR_NOT_BLANK + * BUSY + * + **********************************************************************/ +IAP_STATUS_CODE BlankCheckSector(uint32_t start_sec, uint32_t end_sec, + uint32_t *first_nblank_loc, + uint32_t *first_nblank_val) +{ + IAP_COMMAND_Type command; + + command.cmd = IAP_BLANK_CHECK; // Prepare Sector for Write + command.param[0] = start_sec; // Start Sector + command.param[1] = end_sec; // End Sector + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + if(command.status == SECTOR_NOT_BLANK) + { + // Update out value + if(first_nblank_loc != NULL) + *first_nblank_loc = command.result[0]; + if(first_nblank_val != NULL) + *first_nblank_val = command.result[1]; + } + + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Read part identification number + * + * @param[out] partID Part ID + * + * @return CMD_SUCCESS + * + **********************************************************************/ +IAP_STATUS_CODE ReadPartID(uint32_t *partID) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_READ_PART_ID; + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + if(command.status == CMD_SUCCESS) + { + if(partID != NULL) + *partID = command.result[0]; + } + + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Read boot code version. The version is interpreted as .. + * + * @param[out] major The major + * @param[out] minor The minor + * + * @return CMD_SUCCESS + * + **********************************************************************/ +IAP_STATUS_CODE ReadBootCodeVer(uint8_t *major, uint8_t* minor) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_READ_BOOT_VER; + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + if(command.status == CMD_SUCCESS) + { + if(major != NULL) + *major = (command.result[0] >> 8) & 0xFF; + if(minor != NULL) + *minor = (command.result[0]) & 0xFF; + } + + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Read Device serial number. + * + * @param[out] uid Serial number. + * + * @return CMD_SUCCESS + * + **********************************************************************/ +IAP_STATUS_CODE ReadDeviceSerialNum(uint32_t *uid) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_READ_SERIAL_NUMBER; + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + if(command.status == CMD_SUCCESS) + { + if(uid != NULL) + { + uint32_t i = 0; + for(i = 0; i < 4; i++) + uid[i] = command.result[i]; + } + } + + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief compare the memory contents at two locations. + * + * @param[in] addr1 The address of the 1st buffer (in RAM/Flash). + * @param[in] addr2 The address of the 2nd buffer (in RAM/Flash). + * @param[in] size Number of bytes to be compared; should be a multiple of 4. + * + * @return CMD_SUCCESS + * COMPARE_ERROR + * COUNT_ERROR (Byte count is not a multiple of 4) + * ADDR_ERROR + * ADDR_NOT_MAPPED + * + **********************************************************************/ +IAP_STATUS_CODE Compare(uint8_t *addr1, uint8_t *addr2, uint32_t size) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_COMPARE; + command.param[0] = (uint32_t)addr1; + command.param[1] = (uint32_t)addr2; + command.param[2] = size; + IAP_Call (&command.cmd, &command.status); // Call IAP Command + + return (IAP_STATUS_CODE)command.status; +} + +/*********************************************************************//** + * @brief Re-invoke ISP. + * + * @param[in] None. + * + * @return None. + * + **********************************************************************/ +void InvokeISP(void) +{ + IAP_COMMAND_Type command; + command.cmd = IAP_REINVOKE_ISP; + IAP_Call (&command.cmd, &command.status); // Call IAP Command +} + +/** + * @} + */ + + +#endif /*_IAP*/ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_lcd.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_lcd.c new file mode 100644 index 0000000000000000000000000000000000000000..ea2f6b5cdbbe15220a9fd883c4a306130c14c1f4 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_lcd.c @@ -0,0 +1,856 @@ +/********************************************************************** +* $Id$ lpc_lcd.c 2011-10-14 +*//** +* @file lpc_lcd.c +* @brief Contains all functions support for LCD firmware library +* on LPC +* @version 1.0 +* @date 14. October. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _LCD + +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" +#include "lpc_gpio.h" +#include "lpc_lcd.h" + +uint32_t lcd_hsize = 0, lcd_vsize = 0; +uint32_t lcd_cursor_base_addr = 0; +uint32_t lcd_cursor_size = 64; +LCD_Config_Type lcd_config; +static uint8_t bits_per_pixel[] = { 1, 2, 4, 8, 16, 32, 16, 16 }; +uint32_t rect[1024]; + + +static void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig); +static void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig); +static void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig); +static void LCD_CtrlSetup(LCD_Config_Type* pConfig); + +/** @addtogroup LCD_Private_Functions LCD Private Function + * @ingroup LCD + * @{ + */ + + +/*********************************************************************//** + * @brief Init LCD. The input clock is CClk + * + * @param[in] pConfig Configuration Information + * + * @return LCD_FUNC_OK Execute successfully + * LCD_FUNC_ERR Error occurred. + * + **********************************************************************/ +LCD_RET_CODE LCD_Init (LCD_Config_Type* pConfig) +{ + uint8_t clkdiv; + + if(pConfig == NULL) + return LCD_FUNC_ERR; + + if(pConfig->big_endian_byte & !pConfig->big_endian_pixel) + return LCD_FUNC_ERR; + + lcd_config = *pConfig; + + // Assign pins + PINSEL_ConfigPin(0,4,7); + PINSEL_ConfigPin(0,5,7); + PINSEL_ConfigPin(0,6,7); + PINSEL_ConfigPin(0,7,7); + PINSEL_ConfigPin(0,8,7); + PINSEL_ConfigPin(0,9,7); + PINSEL_ConfigPin(1,20,7); + PINSEL_ConfigPin(1,21,7); + PINSEL_ConfigPin(1,22,7); + PINSEL_ConfigPin(1,23,7); + PINSEL_ConfigPin(1,24,7); + PINSEL_ConfigPin(1,25,7); + PINSEL_ConfigPin(1,26,7); + PINSEL_ConfigPin(1,27,7); + PINSEL_ConfigPin(1,28,7); + PINSEL_ConfigPin(1,29,7); + PINSEL_ConfigPin(2,0,7); + PINSEL_ConfigPin(2,1,7); + PINSEL_ConfigPin(2,2,7); + PINSEL_ConfigPin(2,3,7); + PINSEL_ConfigPin(2,4,7); + PINSEL_ConfigPin(2,5,7); + PINSEL_ConfigPin(2,6,7); +#ifdef CORE_M4 + PINSEL_ConfigPin(0,10,7); +#else + PINSEL_ConfigPin(2,7,7); +#endif + PINSEL_ConfigPin(2,8,7); + PINSEL_ConfigPin(2,9,7); + PINSEL_ConfigPin(2,11,7); + PINSEL_ConfigPin(2,12,7); + PINSEL_ConfigPin(2,13,7); + PINSEL_ConfigPin(4,28,7); + PINSEL_ConfigPin(4,29,7); + + //Turn on LCD clock + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE); + + // Set clock + LPC_LCD->POL &= ~(0x01 << 5); + if( pConfig->panel_clk > 0) { + clkdiv = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / pConfig->panel_clk - 1; + LPC_SC->LCD_CFG = clkdiv & 0x1F; + LPC_LCD->POL |=(1<<26); + } + + // init Horizontal Timing + LCD_SetHorizontalTiming(&pConfig->hConfig); + + // Init Vertical Timing + LCD_SetVertialTiming(&pConfig->vConfig); + + // Set Polarity + LCD_SetPolarity(pConfig->lcd_type, &pConfig->polarity); + + if(NULL != pConfig->lcd_palette) + { + LCD_SetPalette(pConfig->lcd_palette); + } + + // Set Base address + LCD_SetBaseAddress(LCD_PANEL_UPPER, pConfig->lcd_panel_upper); + LCD_SetBaseAddress(LCD_PANEL_LOWER, pConfig->lcd_panel_lower); + + // Setup + LCD_CtrlSetup(pConfig); + + return LCD_FUNC_OK; + + +} +/*********************************************************************//** + * @brief Horizontal Timing Setting + * + * @param[in] pConfig Configuration Information + * + * @return None. + * + **********************************************************************/ +void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig) +{ + LPC_LCD->TIMH = 0; //reset TIMH before set value + LPC_LCD->TIMH |= ((pConfig->hbp - 1)& 0xFF)<<24; + LPC_LCD->TIMH |= ((pConfig->hfp - 1)& 0xFF)<<16; + LPC_LCD->TIMH |= ((pConfig->hsw - 1)& 0xFF)<<8; + LPC_LCD->TIMH |= ((pConfig->ppl/16 - 1)& 0x3F)<<2; + lcd_hsize = pConfig->ppl; +} + +/*********************************************************************//** + * @brief Vertical Timing Setting + * + * @param[in] pConfig Configuration Information + * + * @return None. + * + **********************************************************************/ +void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig) +{ + LPC_LCD->TIMV = 0; //reset TIMV value before setting + LPC_LCD->TIMV |= ((pConfig->vbp)& 0xFF)<<24; + LPC_LCD->TIMV |= ((pConfig->vfp)& 0xFF)<<16; + LPC_LCD->TIMV |= ((pConfig->vsw - 1)& 0x3F)<<10; + LPC_LCD->TIMV |= ((pConfig->lpp - 1)& 0x03FF)<<0; + lcd_vsize = pConfig->lpp; +} + +/*********************************************************************//** + * @brief Polarity Setting + * + * @param[in] pConfig Configuration Information + * @param[in] lcd_type It can be: + * - LCD_STN_MONOCHROME + * - LCD_STN_COLOR + * - LCD_TFT + * + * @return None. + * + **********************************************************************/ +void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig) +{ + // LCDFP pin is active LOW and inactive HIGH + if(pConfig->invert_vsync) + LPC_LCD->POL |= (1<<11); + else + LPC_LCD->POL &= ~(1<<11); + // LCDLP pin is active LOW and inactive HIGH + if(pConfig->invert_hsync) + LPC_LCD->POL |= (1<<12); + else + LPC_LCD->POL &= ~(1<<12); + // data is driven out into the LCD on the falling edge + if(pConfig->invert_panel_clock) + LPC_LCD->POL |= (1<<13); + else + LPC_LCD->POL &= ~(1<<13); + + // active high + if(pConfig->active_high) { + LPC_LCD->POL &= ~(1<<14); + } + else + { + LPC_LCD->POL |= (1<<14); + } + + LPC_LCD->POL &= ~(0x3FF <<16); + LPC_LCD->POL |= (pConfig->cpl - 1)<<16; + + if(lcd_type == LCD_STN_COLOR || lcd_type == LCD_STN_MONOCHROME) + LPC_LCD->POL |= (pConfig->acb & 0x1F) << 6; + } + +/*********************************************************************//** + * @brief Set base address of frame buffer + * + * @param[in] panel identify which panel is. + * @param[in] pAddress base address of the inputted panel. + * + * @return None. + * + **********************************************************************/ +void LCD_SetBaseAddress(LCD_PANEL panel, uint32_t pAddress) +{ + // Frame Base Address doubleword aligned + if(panel == LCD_PANEL_UPPER) + LPC_LCD->UPBASE = pAddress & ~7UL ; + else + LPC_LCD->LPBASE = pAddress & ~7UL ; +} + +/*********************************************************************//** + * @brief LCD Setup. + * + * @param[in] pConfig Configuration information. + * + * @return None. + * + **********************************************************************/ +void LCD_CtrlSetup(LCD_Config_Type* pConfig) +{ + // disable LCD controller + LPC_LCD->CTRL = 0; + + // bpp + LPC_LCD->CTRL &= ~(0x07 <<1); + LPC_LCD->CTRL |=((pConfig->lcd_bpp & 0x07)<<1); + + if(pConfig->lcd_type == LCD_TFT) { + LPC_LCD->CTRL |= (0x01 << 5); // TFT + } + else { + // Color/Mono + if(pConfig->lcd_type == LCD_STN_COLOR) { + LPC_LCD->CTRL &= ~ (0x01 << 4); // Color + } + else if (pConfig->lcd_type == LCD_STN_MONOCHROME) { + LPC_LCD->CTRL |= (0x01 << 4); // Mono + } + + // STN/TFT + LPC_LCD->CTRL &= ~ (0x01 << 5); // STN + + // Mono4/8 + if(pConfig->lcd_mono8) + LPC_LCD->CTRL |= (0x01 << 6); + else + LPC_LCD->CTRL &= ~(0x01 << 6); + + // Single/dual + if(pConfig->lcd_dual) + LPC_LCD->CTRL |= (0x01 << 7); + else + LPC_LCD->CTRL &= ~(0x01 << 7); + } + + // notmal output + if(pConfig->lcd_bgr) + LPC_LCD->CTRL |= (1<<8); // BGR + else + LPC_LCD->CTRL &= ~(1<<8); // RGB + + // Byte order + if(pConfig->big_endian_byte) + LPC_LCD->CTRL |= (1<<9); + else + LPC_LCD->CTRL &= ~(1<<9); + + // Pixel order + if(pConfig->big_endian_pixel) + LPC_LCD->CTRL |= (1<<10); + else + LPC_LCD->CTRL &= ~(1<<10); + + // disable power + LPC_LCD->CTRL &= ~(1<<11); +} + +/*********************************************************************//** + * @brief Enable/disable LCD Display. + * + * @param[in] bEna 0: disable, 1: enable. + * + * @return None. + * + **********************************************************************/ +void LCD_Enable (Bool bEna) +{ + volatile uint32_t i; + if (bEna) + { + LPC_LCD->CTRL |= (1<<0); + for(i = LCD_PWR_ENA_DIS_DLY; i; i--); + LPC_LCD->CTRL |= (1<<11); + } + else + { + LPC_LCD->CTRL &= ~(1<<11); + for(i = LCD_PWR_ENA_DIS_DLY; i; i--); + LPC_LCD->CTRL &= ~(1<<0); + } +} + + +/*********************************************************************//** + * @brief Set palette. + * + * @param[in] bEna 0: disable, 1: enable. + * + * @return None. + * + **********************************************************************/ +void LCD_SetPalette (const uint8_t* pPallete) +{ + uint32_t i; + uint32_t size = (0x01 << bits_per_pixel[lcd_config.lcd_bpp])/2 ; + uint32_t * pDst = (uint32_t *)LPC_LCD->PAL; + uint32_t * pInput = (uint32_t*) pPallete; + + for (i = 0; i < size; i++) + { + *pDst = *pInput; + pDst++; + pInput++; + } +} +/*********************************************************************//** + * @brief Get word offset for the given pixel + * + * @param[in] x x position of input pixel + * @param[in] y y position of input pixel + * + * @return Offset + * + **********************************************************************/ +uint32_t LCD_GetWordOffset(uint32_t x, uint32_t y) +{ + uint32_t pixel_num = x + y*lcd_hsize; + + return (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])/32; +} +/*********************************************************************//** + * @brief Get bit offset for the given pixel + * + * @param[in] x x position of input pixel + * @param[in] y y position of input pixel + * + * @return Offset + * + **********************************************************************/ +uint32_t LCD_GetBitOffset(uint32_t x, uint32_t y) +{ + uint32_t pixel_num; + uint32_t ofs; + pixel_num = x + y*lcd_hsize; + + ofs = (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])%32; + + if(lcd_config.big_endian_pixel & lcd_config.big_endian_byte) + { + ofs = 32 - bits_per_pixel[lcd_config.lcd_bpp] - ofs; + } + else if (lcd_config.big_endian_pixel & !lcd_config.big_endian_byte) + { + if(bits_per_pixel[lcd_config.lcd_bpp] < 8) + { + ofs = (ofs/8)*8 + (8 - (ofs%8)-bits_per_pixel[lcd_config.lcd_bpp]); + } + } + return ofs; +} + + + +/*********************************************************************//** + * @brief Copy pixel values from image buffer to frame buffer. + * + * @param[in] panel It can be: + * - LCD_PANEL_UPPER + * - LCD_PANEL_LOWER + * @param[in] pPain point to image buffer. + * + * @return None. + * + **********************************************************************/ +void LCD_SetImage(LCD_PANEL panel, const uint8_t *pPain) +{ + volatile uint32_t i; + uint32_t * pWordDst = NULL; + uint8_t* pByteDst = NULL; + uint32_t bytes_num; + + if(panel == LCD_PANEL_UPPER) + pWordDst = (uint32_t*) LPC_LCD->UPBASE; + else + pWordDst = (uint32_t*) LPC_LCD->LPBASE; + + pByteDst = (uint8_t*) pWordDst; + bytes_num = ((lcd_hsize * lcd_vsize) * bits_per_pixel[lcd_config.lcd_bpp]) /8; + + if (NULL == pPain) + { + // clear display memory + for( i = 0; bytes_num > i; i++) + { + *pByteDst++ = 0; + } + } + else + { + // set display memory + for(i = 0; bytes_num > i; i++) + { + *pByteDst++ = *pPain++; + } + } + + for(i = LCD_PWR_ENA_DIS_DLY; i; i--); +} +/*********************************************************************//** + * @brief Draw a pixel on the given panel. + * + * @param[in] panel It can be: + * - LCD_PANEL_UPPER + * - LCD_PANEL_LOWER + * @param[in] X_Left X position. + * @param[in] Y_Up Y position. + * @param[in] color Color which is placed to the given pixel. + * + * @return None. + * + **********************************************************************/ +void LCD_PutPixel (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up, LcdPixel_t color) +{ + uint32_t k; + uint32_t * pWordData = NULL; + uint8_t* pByteData = NULL; + uint32_t bitOffset; + uint8_t* pByteSrc = (uint8_t*)&color; + uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp]; + uint8_t bytes_per_pixel = bpp/8; + uint32_t start_bit; + + if((X_Left >= lcd_hsize)||(Y_Up >= lcd_vsize)) + return; + + if(panel == LCD_PANEL_UPPER) + pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up); + else + pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up); + + bitOffset = LCD_GetBitOffset(X_Left,Y_Up); + pByteData = (uint8_t*) pWordData; + pByteData += bitOffset/8; + + start_bit = bitOffset%8; + + if(bpp < 8) + { + uint8_t bit_pos = start_bit; + uint8_t bit_ofs = 0; + for(bit_ofs = 0;bit_ofs > (k+bit_ofs)) & 0x01) << bit_pos; + } + } + else + { + for(k = 0; k < bytes_per_pixel; k++) + { + *(pByteData+ k) = *pByteSrc++; + } + } +} +/*********************************************************************//** + * @brief Place given image to given position. + * + * @param[in] panel It can be: + * - LCD_PANEL_UPPER + * - LCD_PANEL_LOWER + * @param[in] X_Left Start X position. + * @param[in] Y_Up Start Y position. + * @param[in] pBmp Image information. + * @param[in] Mask Mask on pixel values. + * + * @return None. + * + **********************************************************************/ +void LCD_LoadPic (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up, + Bmp_t * pBmp, uint32_t Mask) +{ + uint32_t i, j, k, inc; + uint32_t * pWordData = NULL; + uint8_t* pByteData = NULL; + uint32_t bitOffset; + uint8_t* pByteSrc = (uint8_t*) pBmp->pPicStream; + uint32_t X_LeftHold = X_Left; + uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp]; + uint8_t bytes_per_pixel = bpp/8; + uint8_t pixels_per_byte = 8/bpp; + uint32_t hsize, vsize; + uint32_t start_bit; + + if(pBmp->BytesPP == 0) + pBmp->BytesPP = bytes_per_pixel; + + hsize = pBmp->H_Size; + vsize = pBmp->V_Size; + inc = (pixels_per_byte > 0) ? pixels_per_byte:1; + + for(i = 0; i < vsize; i++) + { + if(panel == LCD_PANEL_UPPER) + pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up); + else + pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up); + + bitOffset = LCD_GetBitOffset(X_Left,Y_Up); + pByteData = (uint8_t*) pWordData; + pByteData += bitOffset/8; + + start_bit = bitOffset%8; + + if(pBmp->BytesPP > 0) + pByteSrc = (uint8_t*) pBmp->pPicStream + i*hsize*pBmp->BytesPP; // storage of each line must be word alignment + else + pByteSrc = (uint8_t*) pBmp->pPicStream + (i*hsize*pBmp->BitsPP + 7)/8; // storage of each line must be word alignment + + X_LeftHold = X_Left; + + for(j = 0; j <= hsize; j+= inc) + { + if((X_LeftHold >= lcd_hsize) || (X_LeftHold - X_Left >= hsize)) + break; + if(bpp < 8) + { + uint8_t bit_pos = start_bit; + uint8_t bit_ofs = 0; + for(k = 0; k < 8; k+= bpp) + { + for(bit_ofs = 0;bit_ofs > (k+bit_ofs)) & 0x01) << bit_pos; + } + if(lcd_config.big_endian_byte && lcd_config.big_endian_pixel) + { + if(bit_pos >= bpp*2) + bit_pos -= bpp*2; + else + { + bit_pos = 8-bpp; + if((((uint32_t)pByteData)%4) == 0) + pByteData += 7; // change to next word + else + pByteData--; // change to previous byte + } + } + else if( !lcd_config.big_endian_byte && lcd_config.big_endian_pixel) + { + if(bit_pos >= bpp*2) + bit_pos -= bpp*2; + else + { + bit_pos = 8-bpp; + pByteData++; // change to next byte + } + } + else + { + if(bit_pos >= 8) + { + bit_pos = 0; + pByteData++; // change to next byte + } + + } + X_LeftHold++; + if((X_LeftHold >= lcd_hsize) || + (X_LeftHold - X_Left >= hsize)) + break; + } + pByteSrc++; + continue; + } + else + { + for(k = 0; k < pBmp->BytesPP; k++) + { + *(pByteData+ k) = *pByteSrc++ ^ Mask; + } + if(lcd_config.big_endian_byte) + { + if((uint32_t)pByteData %4 > 0) + pByteData -= bytes_per_pixel; + else + pByteData += 8 - bytes_per_pixel; + } + else + pByteData+= bytes_per_pixel; + X_LeftHold++; + } + } + if(Y_Up++ >= lcd_vsize) + { + break; + } + } +} + +/*********************************************************************//** + * @brief Fill a rectangle. + * + * @param[in] panel It can be: + * - LCD_PANEL_UPPER + * - LCD_PANEL_LOWER + * @param[in] startx Start X position. + * @param[in] endy End X position. + * @param[in] starty Start Y position. + * @param[in] endy End Y position. + * + * @return None. + * + **********************************************************************/ +void LCD_FillRect (LCD_PANEL panel, uint32_t startx,uint32_t endx, + uint32_t starty, uint32_t endy, + LcdPixel_t color) +{ + uint32_t x, xs, xe, ys, ye; + uint8_t bpp, pixels_per_word; + uint32_t word_val, mask; + uint32_t max_vsize = 0; + Bmp_t bitmap; + uint32_t hsize, vsize; + + bpp = bits_per_pixel[lcd_config.lcd_bpp]; + pixels_per_word = 32/bpp; + + mask = 0; + for( x = 0; x < bpp; x++) + mask |= 0x01 << x; + + color &= mask; + + word_val = 0; + for(x = 0; x < pixels_per_word; x++) + word_val |= color << (x*bpp); + + ys = (starty > endy) ? endy : starty; + ye = (starty > endy) ? starty : endy; + + xs = (startx > endx) ? endx : startx; + xe = (startx > endx) ? startx : endx; + + bitmap.BitsPP = bpp; + bitmap.BytesPP = bpp/8; + hsize = xe - xs + 1; + bitmap.H_Size = hsize; + vsize = ye - ys + 1; + bitmap.pPicStream = (uint8_t*)rect; + + max_vsize = ((1024 * 32)/(hsize*bpp)); + + for( x = 0; x < 1024; x++) + { + rect[x] = word_val; + } + + while(1) + { + if(max_vsize >= vsize) + { + bitmap.V_Size = vsize; + LCD_LoadPic(panel,xs,ys, &bitmap, 0); + break; + } + else { + bitmap.V_Size = max_vsize; + vsize -= bitmap.V_Size; + LCD_LoadPic(panel,xs,ys, &bitmap, 0); + ys += max_vsize; + } + } + + +} + +/*********************************************************************//** + * @brief Configure display of cursor. + * + * @param[in] pConfig Configuration information. + * + * @return None. + * + **********************************************************************/ +void LCD_Cursor_Cfg(LCD_Cursor_Config_Type* pConfig) +{ + if(pConfig->size32) { + LPC_LCD->CRSR_CFG &= ~(0x01 << 0); + lcd_cursor_size = 32; + } + else { + LPC_LCD->CRSR_CFG |= (0x01 << 0); + lcd_cursor_size = 64; + } + + if(pConfig->framesync) + LPC_LCD->CRSR_CFG &= ~(0x01 << 1); + else + LPC_LCD->CRSR_CFG |= (0x01 << 1); + + lcd_cursor_base_addr = pConfig->baseaddress; + + LPC_LCD->CRSR_PAL0 = pConfig->palette[0].Red | + pConfig->palette[0].Green << 8 | + pConfig->palette[0].Blue << 16; + LPC_LCD->CRSR_PAL1 = pConfig->palette[1].Red | + pConfig->palette[1].Green << 8 | + pConfig->palette[1].Blue << 16; + +} +/*********************************************************************//** + * @brief Enable/disable cursor display. + * + * @param[in] enable 0: disable, 1: enable. + * @param[in] cursor identify which cursor image is used. + * + * @return None. + * + **********************************************************************/ +void LCD_Cursor_Enable(int enable, int cursor) +{ + if(enable) { + LPC_LCD->CRSR_CTRL |= (1<<0); + LPC_LCD->CRSR_CTRL |= (cursor<<4); + } + else { + LPC_LCD->CRSR_CTRL &= ~(1<<0); + } +} + + +/*********************************************************************//** + * @brief move the cursor to the inputted position. + * + * @param[in] x Position in x-direction. + * @param[in] y Position in y-direction. + * + * @return None. + * + **********************************************************************/ +void LCD_Move_Cursor(int x, int y) +{ + LPC_LCD->CRSR_CLIP = 0; + LPC_LCD->CRSR_XY = 0; + if(0 <= x) + {//no clipping + LPC_LCD->CRSR_XY |= (x & 0x3FF); + } + else + {//clip x + LPC_LCD->CRSR_CLIP |= -x; + } + + if(0 <= y) + {//no clipping + + LPC_LCD->CRSR_XY |= (y << 16); + } + else + {//clip y + LPC_LCD->CRSR_CLIP |= (-y << 8); + } +} + +/*********************************************************************//** + * @brief Set the cursor image. + * + * @param[in] pCursor point to cursor image. + * @param[in] cursor cursor image number. It has no meaning when cursor size is 64x64 + * @param[in] cursor cursor size in words. + * + * @return None. + * + **********************************************************************/ +void LCD_Cursor_SetImage (const uint32_t *pCursor, int cursor, int size) +{ + uint32_t i ; + uint32_t * pDst = (uint32_t *)lcd_cursor_base_addr; + + if(lcd_cursor_size == 32) + pDst += cursor*GET_CURSOR_IMG_SIZE(lcd_cursor_size); + + + for(i = 0; i < size ; i++) + { + *pDst = *pCursor; + pDst++; + pCursor++; + } +} + +/** + * @} + */ + +#endif /*_LCD*/ + + + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_mci.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_mci.c new file mode 100644 index 0000000000000000000000000000000000000000..813d599be29311f765c27bbd68373df9af725044 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_mci.c @@ -0,0 +1,2508 @@ +/********************************************************************** +* $Id$ lpc_mci.c 2011-06-02 +*//** +* @file lpc_mci.c +* @brief Contains all functions support for MCI firmware library +* on LPC +* @version 2.0 +* @date 29. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _MCI + +#include "LPC407x_8x_177x_8x.h" +#include "lpc_types.h" +#include "lpc_mci.h" +#include "lpc_gpdma.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +#define DMA_MCI_SIZE BLOCK_LENGTH + +#define MCI_DMA_WRITE_CHANNEL (0) +#define MCI_DMA_READ_CHANNEL (1) + +#define _SHIFT(x) (1 << x) +#define _XSHIFT(x, y) (x << y) + +#define SHIFT_(x) (1 >> x) +#define XSHIFT_(x, y) (x >> y) + +#define MCI_ACMD41_HCS_POS (30) + +#define MCI_PWRCTRL_BMASK (0xC3) + +#define MCI_PWRCTRL_OPENDRAIN_POS (6) +#define MCI_PWRCTRL_OPENDRAIN_NUMBIT (1) +#define MCI_PWRCTRL_OPENDRAIN_BMASK (0x01) + + +volatile uint32_t Mci_Data_Xfer_End = 0; + +volatile uint32_t Mci_Data_Xfer_ERR = 0; + +volatile uint8_t fifo_plane = 0; + +volatile uint32_t CardRCA; + +volatile uint8_t CCS; + +volatile en_Mci_CardType MCI_CardType; + +// Terminal Counter flag, Error Counter flag for Channel 0 +uint32_t dmaWrCh_TermianalCnt, dmaWrCh_ErrorCnt; +uint32_t dmaRdCh_TermianalCnt, dmaRdCh_ErrorCnt; + + +uint32_t MCI_SettingDma(uint8_t* memBuf, uint32_t ChannelNum, uint32_t DMAMode ); + +int32_t MCI_ReadFifo(uint32_t * dest); +int32_t MCI_WriteFifo(uint32_t * src); + +void MCI_TXEnable( void ); +void MCI_RXEnable( void ); +void MCI_TXDisable( void ); +void MCI_RXDisable( void ); + +void MCI_CmdProcess( void ); +void MCI_DataErrorProcess( void ); +void MCI_DataErrorProcess( void ); +void MCI_DATA_END_InterruptService( void ); +void MCI_FIFOInterruptService( void ); + +int32_t MCI_CheckStatus(uint8_t expect_status); + + + +volatile uint8_t* dataSrcBlock = (uint8_t *) MCI_DMA_SRC_ADDR; +volatile uint8_t* dataDestBlock = (uint8_t *) MCI_DMA_DST_ADDR; + +volatile uint32_t txBlockCnt=0, rxBlockCnt=0; + +/** @addtogroup MCI_Private_Functions MCI Private Function + * @ingroup MCI + * @{ + */ + +#if MCI_DMA_ENABLED +/*********************************************************************//** + * @brief Do setting GPDMA for MCI working + * + * @param[in] DMAMode set for the Type of DMA Transfer. It may be memory + * to peripheral (M2P) or peripheral to memory (P2M) + * in MCI working + * + * @param[in] ChannelNum which channel is used for current transfer with + * DMA compent + * + * @param[in] memBuf point to a UINT8 buffer. In 2 cases of DMAMode + * seperated: + * - M2P: it is the source address that hold the + * expected buffer to transfer + * - P2M: it is the destination address that will store + * data that retrieved from the peripheral (the Card in slot) + * + * @return None + * + * @note This is only required if DMA support is enabled + **********************************************************************/ +uint32_t MCI_SettingDma(uint8_t* memBuf, uint32_t ChannelNum, uint32_t DMAMode ) +{ + GPDMA_Channel_CFG_Type GPDMACfg; + + // Transfer size + GPDMACfg.TransferSize = DMA_MCI_SIZE; + // Transfer width + GPDMACfg.TransferWidth = GPDMA_WIDTH_WORD; + // Transfer type + GPDMACfg.TransferType = DMAMode; + // Linker List Item - unused + GPDMACfg.DMALLI = 0; + + /* USB RAM is used for test. + Please note, Ethernet has its own SRAM, but GPDMA can't access + that. GPDMA can access USB SRAM and IRAM. Ethernet DMA controller can + access both IRAM and Ethernet SRAM. */ + GPDMACfg.ChannelNum = ChannelNum; + + if ( DMAMode == GPDMA_TRANSFERTYPE_M2P_DEST_CTRL ) + { + /* Ch0 set for M2P transfer from mempry to MCI FIFO. */ + // Source memory + GPDMACfg.SrcMemAddr = (uint32_t)memBuf; + // Destination memory + GPDMACfg.DstMemAddr = (uint32_t)LPC_MCI->FIFO; + + // Source connection + GPDMACfg.SrcConn = 0; + // Destination connection + GPDMACfg.DstConn = GPDMA_CONN_MCI; + + } + else if ( DMAMode == GPDMA_TRANSFERTYPE_P2M_SRC_CTRL ) + { + /* Ch0 set for P2M transfer from MCI FIFO to memory. */ + // Source memory + GPDMACfg.SrcMemAddr = (uint32_t)LPC_MCI->FIFO; + // Destination memory + GPDMACfg.DstMemAddr = (uint32_t)memBuf; + + // Source connection + GPDMACfg.SrcConn = GPDMA_CONN_MCI; + // Destination connection + GPDMACfg.DstConn = 0; + } + else + { + return ( FALSE ); + } + + // Setup channel with given parameter + GPDMA_Setup(&GPDMACfg); + + // Enable GPDMA channel + GPDMA_ChannelCmd(ChannelNum, ENABLE); + + /* Enable GPDMA interrupt */ + NVIC_EnableIRQ(DMA_IRQn); + + return (TRUE); +} + + +/*********************************************************************//** + * @brief GPDMA interrupt handler sub-routine + * + * @param None + * + * @return None + * + * @note This is only executed if DMA support is enabled + **********************************************************************/ +void MCI_DMA_IRQHandler (void) +{ + // check GPDMA interrupt on channel 0 + if (GPDMA_IntGetStatus(GPDMA_STAT_INT, MCI_DMA_WRITE_CHANNEL)) + { + //check interrupt status on channel 0 + // Check counter terminal status + if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, MCI_DMA_WRITE_CHANNEL)) + { + // Clear terminate counter Interrupt pending + GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, MCI_DMA_WRITE_CHANNEL); + + dmaWrCh_TermianalCnt++; + } + if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, MCI_DMA_WRITE_CHANNEL)) + { + // Clear error counter Interrupt pending + GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, MCI_DMA_WRITE_CHANNEL); + + dmaWrCh_ErrorCnt++; + } + } + else if (GPDMA_IntGetStatus(GPDMA_STAT_INT, MCI_DMA_READ_CHANNEL)) + { + //check interrupt status on channel 0 + // Check counter terminal status + if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, MCI_DMA_READ_CHANNEL)) + { + // Clear terminate counter Interrupt pending + GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, MCI_DMA_READ_CHANNEL); + + dmaRdCh_TermianalCnt++; + } + if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, MCI_DMA_READ_CHANNEL)) + { + // Clear error counter Interrupt pending + GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, MCI_DMA_READ_CHANNEL); + + dmaRdCh_ErrorCnt++; + } + } +} +#endif + + +/*********************************************************************//** + * @brief Read data from FIFO (after a transmission with card) to + * a destination buffer + * + * @param[in] *dest The buffer to store the data that read from card + * + * @return MCI_FUNC_OK + *************************************************************************/ +int32_t MCI_ReadFifo(uint32_t * dest) +{ + uint8_t i; + uint8_t start, end; + + if(fifo_plane == 0) + { + start = 0; + end = 7; + } + else + { + start = 8; + end = 15; + } + fifo_plane = (fifo_plane) ? 0:1; + + for (i = start; i <= end; i++) + { + *dest = LPC_MCI->FIFO[i]; + + dest++; + } + + return MCI_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Write data from a source buffer to FIFO for transmission + * + * @param[in] *src The buffer hold the data need to write to card + * + * @return MCI_FUNC_OK + *************************************************************************/ +int32_t MCI_WriteFifo(uint32_t * src) +{ + uint8_t i; + uint8_t start, end; + + if(fifo_plane == 0) + { + start = 0; + end = 7; + } + else + { + start = 8; + end = 15; + } + fifo_plane = (fifo_plane) ? 0:1; + + for (i = start; i <= end; i++) + { + LPC_MCI->FIFO[i] = *src; + + src++; + } + + return MCI_FUNC_OK; +} + + +/*********************************************************************//** + * @brief Enable Transmit data interrupt + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_TXEnable( void ) +{ +#if MCI_DMA_ENABLED + LPC_MCI->MASK0 |= ((DATA_END_INT_MASK)|(ERR_TX_INT_MASK)); /* Enable TX interrupts only */ +#else + LPC_MCI->MASK0 |= ((FIFO_TX_INT_MASK)|(DATA_END_INT_MASK)|(ERR_TX_INT_MASK)); /* FIFO TX interrupts only */ +#endif + + return; +} + + +/*********************************************************************//** + * @brief Disable Transmit data interrupt + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_TXDisable( void ) +{ +#if MCI_DMA_ENABLED + LPC_MCI->MASK0 &= ~((DATA_END_INT_MASK)|(ERR_TX_INT_MASK)); /* Enable TX interrupts only */ +#else + LPC_MCI->MASK0 &= ~((FIFO_TX_INT_MASK)|(DATA_END_INT_MASK)|(ERR_TX_INT_MASK)); /* FIFO TX interrupts only */ +#endif + + return; +} + + +/*********************************************************************//** + * @brief Enable Receive data interrupt + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_RXEnable( void ) +{ +#if MCI_DMA_ENABLED + LPC_MCI->MASK0 |= ((DATA_END_INT_MASK)|(ERR_RX_INT_MASK)); /* Enable RX interrupts only */ +#else + LPC_MCI->MASK0 |= ((FIFO_RX_INT_MASK)|(DATA_END_INT_MASK)|(ERR_RX_INT_MASK)); /* FIFO RX interrupts only */ +#endif + + return; +} + + +/*********************************************************************//** + * @brief Disable Receive data interrupt + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_RXDisable( void ) +{ +#if MCI_DMA_ENABLED + LPC_MCI->MASK0 &= ~((DATA_END_INT_MASK)|(ERR_RX_INT_MASK)); /* Enable TX interrupts only */ +#else + LPC_MCI->MASK0 &= ~((FIFO_RX_INT_MASK)|(DATA_END_INT_MASK)|(ERR_RX_INT_MASK)); /* FIFO TX interrupts only */ +#endif + + return; +} + +/*********************************************************************//** + * @brief Check if the card is in the given state. + *@param expect_status expected status + * @details Continuously get the card status until the card is ready. if its status matches + * with the given state, return with success. Else, return MCI_FUNC_ERR_STATE. + * If the card is still not ready, return MCI_FUNC_NOT_READY. + * + * @param None + * + * @return MCI_FUNC_OK if all success + *************************************************************************/ +int32_t MCI_CheckStatus(uint8_t expect_status) +{ + int32_t respValue, retval = MCI_FUNC_FAILED; + uint32_t retryCnt = 0xFFFF, i; + while (retryCnt > 0) + { + if (MCI_GetCardStatus(&respValue) != MCI_FUNC_OK) + { + break; + } + else + { + /* The only valid state is TRANS per MMC and SD state diagram. + RCV state may be seen, but, it happens only when TX_ACTIVE or + RX_ACTIVE occurs before the WRITE_BLOCK and READ_BLOCK cmds are + being sent, which is not a valid sequence. */ + if(!(respValue & CARD_STATUS_READY_FOR_DATA )) + { + retval = MCI_FUNC_NOT_READY; + } + else if(CARDSTATEOF(respValue) != expect_status) + { + // If card is in prg state, wait until it changes to trans state + // when "operation complete" + if(CARDSTATEOF(respValue) != CARD_STATE_PRG) + { + return MCI_FUNC_ERR_STATE; + } + } + else + { + return MCI_FUNC_OK; + } + } + retryCnt--; + for(i = 0; i < 0x20; i++); + + } + + return retval; +} + + +/*********************************************************************//** + * @brief Called by MCI interrupt handler to simplify the command + * process. + * + * @param None + * + * @return None + * + * @note In card initialization, the commnad interrupts are disabled + *************************************************************************/ +void MCI_CmdProcess( void ) +{ + uint32_t MCIStatus; + + MCIStatus = LPC_MCI->STATUS; + + if ( MCIStatus & MCI_CMD_CRC_FAIL ) + { + LPC_MCI->CLEAR = MCI_CMD_CRC_FAIL; + } + + if ( MCIStatus & MCI_CMD_TIMEOUT ) + { + LPC_MCI->CLEAR = MCI_CMD_TIMEOUT; + } + + /* Cmd Resp End or Cmd Sent */ + if ( MCIStatus & MCI_CMD_RESP_END ) + { + LPC_MCI->CLEAR = MCI_CMD_RESP_END; + } + + if ( MCIStatus & MCI_CMD_SENT ) + { + LPC_MCI->CLEAR = MCI_CMD_SENT; + } + + if ( MCIStatus & MCI_CMD_ACTIVE ) + { + LPC_MCI->CLEAR = MCI_CMD_ACTIVE; + } + + return; +} + + +/*********************************************************************//** + * @brief Called by MCI interrupt handler to manage error on the bus + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_DataErrorProcess( void ) +{ + uint32_t MCIStatus; + + MCIStatus = LPC_MCI->STATUS; + + if ( MCIStatus & MCI_DATA_CRC_FAIL ) + { + LPC_MCI->CLEAR = MCI_DATA_CRC_FAIL; + } + + if ( MCIStatus & MCI_DATA_TIMEOUT ) + { + LPC_MCI->CLEAR = MCI_DATA_TIMEOUT; + } + + /* Underrun or overrun */ + if ( MCIStatus & MCI_TX_UNDERRUN ) + { + LPC_MCI->CLEAR = MCI_TX_UNDERRUN; + } + + if ( MCIStatus & MCI_RX_OVERRUN ) + { + LPC_MCI->CLEAR = MCI_RX_OVERRUN; + } + + /* Start bit error on data signal */ + if ( MCIStatus & MCI_START_BIT_ERR ) + { + LPC_MCI->CLEAR = MCI_START_BIT_ERR; + } + + Mci_Data_Xfer_End = 0; + Mci_Data_Xfer_ERR = MCIStatus; + return; +} + + +/*********************************************************************//** + * @brief Called by MCI interrupt handler. This is the last interrupt + * manipulates the process of the data-block write and read + * to/with card + * + * @details This service is also used with/without DMA support. It simply + * clears the flag messages the in-process data-block transfer + * has been done/ended + * + * @param None + * + * @return None + *************************************************************************/ +void MCI_DATA_END_InterruptService( void ) +{ + uint32_t MCIStatus; + + MCIStatus = LPC_MCI->STATUS; + if ( MCIStatus & MCI_DATA_END ) /* Data end, and Data block end */ + { + LPC_MCI->CLEAR = MCI_DATA_END; + + Mci_Data_Xfer_End = 0; + + Mci_Data_Xfer_ERR = 0; + + MCI_TXDisable(); + + MCI_RXDisable(); + + return; + } + + if ( MCIStatus & MCI_DATA_BLK_END ) + { + LPC_MCI->CLEAR = MCI_DATA_BLK_END; + + //MCI_TXDisable(); + + return; + } + + /* Tx active */ + if ( MCIStatus & MCI_TX_ACTIVE ) + { + + } + + /* Rx active */ + if ( MCIStatus & MCI_RX_ACTIVE ) + { + + } + + return; +} + + +/*********************************************************************//** + * @brief Called by MCI interrupt handler if requiring to using FIFO + * for data transferring. It copy data to/from FIFO register + * from/to a data buffer. + * + * @param None + * + * @return None + * + * @note This function is done without DMA transfer support + **********************************************************************/ +void MCI_FIFOInterruptService( void ) +{ +#if !MCI_DMA_ENABLED + uint32_t MCIStatus; + + MCIStatus = LPC_MCI->STATUS; + + if ( MCIStatus & (FIFO_TX_INT_MASK ) ) + { + /* empty is multiple of 512 block size */ + if ( MCIStatus & MCI_TX_HALF_EMPTY ) + { + //There's no data, return + if(dataSrcBlock == NULL) + return; + + /* write 8 words to fifo */ + MCI_WriteFifo((uint32_t *)&dataSrcBlock[txBlockCnt]); + + txBlockCnt += 32; + } + + if (txBlockCnt == BLOCK_LENGTH) /* block complete */ + { + dataSrcBlock += BLOCK_LENGTH; + + txBlockCnt = 0; + + /* disable FIFO int until next block write */ + //LPC_MCI->MASK0 &= ~(FIFO_TX_INT_MASK); + + /* wait for SD card to complete sending data i.e MCI_DATA_BLK_END interrupt */ + } + } + else if ( MCIStatus & (FIFO_RX_INT_MASK) ) + { + /* if using RX_HALF_FULL remove one ReadFIFO below */ + if ( MCIStatus & MCI_RX_HALF_FULL ) + { + //There's no store data, return + if(dataDestBlock == NULL) + return; + + /* read 8 words from fifo */ + MCI_ReadFifo((uint32_t *)&dataDestBlock[rxBlockCnt]); + + rxBlockCnt += 32; + } + + /* block complete */ + if (rxBlockCnt == BLOCK_LENGTH) + { + dataDestBlock += BLOCK_LENGTH; + + rxBlockCnt = 0; + } + } +#endif + + return; +} + +/*********************************************************************//** + * @brief MCI_IRQHandler is to manage the reasons that cause the + * interrupt. + * + * @details It controls the data-block writing and reading by access + * the FIFO register. + * It handle the state changes on the MCI bus... + * + * @param None + * + * @return None + **********************************************************************/ +void MCI_IRQHandler (void) +{ + uint32_t MCI_Status; + + MCI_Status = LPC_MCI->STATUS; + + /* handle MCI_STATUS interrupt */ + if ( MCI_Status & DATA_ERR_INT_MASK ) + { + MCI_DataErrorProcess(); + + return; + } + + if ( MCI_Status & DATA_END_INT_MASK ) + { + MCI_DATA_END_InterruptService(); + + return; + } + else if ( MCI_Status & FIFO_INT_MASK ) + { + MCI_FIFOInterruptService(); + + return; + } + else if ( MCI_Status & CMD_INT_MASK ) + { + MCI_CmdProcess(); + + return; + } +} + + +/** + * @} + */ + + + +/** @addtogroup MCI_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Set MCI clock rate, during initialization phase < 400K + * during data phase < 20Mhz + * + * @param[in] ClockRate Clock rate to be set (in Hz) + * + * @return None + **********************************************************************/ +void MCI_Set_MCIClock( uint32_t ClockRate ) +{ + volatile uint32_t i; + uint32_t ClkValue = 0; + uint32_t pclk; + + pclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + ClkValue = (pclk + 2*ClockRate - 1) /(2*ClockRate); + if(ClkValue) + ClkValue -= 1; + + LPC_MCI->CLOCK = (LPC_MCI->CLOCK & ~(0xFF)) | (1 << 8) | ClkValue; + + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK before next write */ + + return; +} + + +/**********************************************************************//** + * @brief Set the Width to 1-bit Bus or 4-bit Bus + * + * @param[in] width buswidth expected to set + * + * @return MCI_FUNC_OK in case of success + *************************************************************************/ +int32_t MCI_SetBusWidth( uint32_t width ) +{ + volatile uint32_t i; + uint8_t bus_width = BUS_WIDTH_1BIT; + + if ( width == SD_1_BIT ) + { + LPC_MCI->CLOCK &= ~(1 << 11); /* 1 bit bus */ + } + else if ( width == SD_4_BIT ) + { + LPC_MCI->CLOCK |= (1 << 11);/* 4 bit bus */ + bus_width = BUS_WIDTH_4BITS; + } + + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + if ( MCI_Acmd_SendBusWidth( bus_width ) != MCI_FUNC_OK ) + { + return(MCI_FUNC_FAILED); + } + } + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Do initialization the MCI block as set its clock, registers, + * setup NVIC for interrupts, configure the pins used for MCI + * function, do initialize the card in slot... + * + * @param[in] powerActiveLevel the power level to activate the card in slot + * + * @return MCI_FUNC_OK in case of success + ***************************************************************************/ +int32_t MCI_Init(uint8_t powerActiveLevel ) +{ + volatile uint32_t i; + + MCI_CardType = MCI_CARD_UNKNOWN; + + // Following block of code added to ensure card VCC drops to zero + // before card is initialized + + // Force all MCI control pins to basic I/O mode + LPC_IOCON->P1_2 &= ~0x1F; /* SD_CLK @ P1.2 */ + LPC_IOCON->P1_3 &= ~0x1F; /* SD_CMD @ P1.3 */ + LPC_IOCON->P1_5 &= ~0x1F; /* SD_PWR @ P1.5 */ + LPC_IOCON->P1_6 &= ~0x1F; /* SD_DAT_0 @ P1.6 */ + LPC_IOCON->P1_7 &= ~0x1F; /* SD_DAT_1 @ P1.7 */ + LPC_IOCON->P1_11 &= ~0x1F; /* SD_DAT_2 @ P1.11 */ + LPC_IOCON->P1_12 &= 0x1F; /* SD_DAT_3 @ P1.12 */ + + // Set all MCI pins to outputs + LPC_GPIO1->DIR |= 0x18EC; + + // Force all pins low (except power control pin) + LPC_GPIO1->CLR = 0x1000; + LPC_GPIO1->CLR = 0x0800; + LPC_GPIO1->CLR = 0x0080; + LPC_GPIO1->CLR = 0x0040; + + LPC_GPIO1->SET = 0x0020; + + LPC_GPIO1->CLR = 0x0008; + LPC_GPIO1->CLR = 0x0004; + + // Crude delay of 50ms at 120MHz + for ( i = 0; i < 0x100000; i++ ); + + LPC_SC->PCONP |= ( 1 << 28 ); /* Enable clock to the MCI block */ + + if ( LPC_MCI->CLOCK & (1 << 8) ) + { + LPC_MCI->CLOCK &= ~(1 << 8); + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + } + + if ( LPC_MCI->POWER & 0x02 ) + { + LPC_MCI->POWER = 0x00; + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + } + + /* Disable all interrupts for now */ + LPC_MCI->MASK0 = 0; + + //SD_CLK + PINSEL_ConfigPin(1, 2, 2); + + //SD_CMD + PINSEL_ConfigPin(1, 3, 2); + + //SD_PWR + PINSEL_ConfigPin(1, 5, 2); + + //SD_DAT_0 + PINSEL_ConfigPin(1, 6, 2); + + //SD_DAT_1 + PINSEL_ConfigPin(1, 7, 2); + + //SD_DAT_2 + PINSEL_ConfigPin(1, 11, 2); + + //SD_DAT_3 + PINSEL_ConfigPin(1, 12, 2); + + // SD_PWR is active high (follows the output of the SD Card interface block). + if(powerActiveLevel == LOW_LVL) + { + LPC_SC->SCS &= ~ 0x08;//Becase on EA board SD_PWR is active low + } + else + { + LPC_SC->SCS |= 0x08; + } + + //Setting for timeout problem + LPC_MCI->DATATMR = 0x1FFFFFFF; + + /*set up clocking default mode, clear any registers as needed */ + LPC_MCI->COMMAND = 0; + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + LPC_MCI->DATACTRL = 0; + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + LPC_MCI->CLEAR = 0x7FF; /* clear all pending interrupts */ + + LPC_MCI->POWER = 0x02; /* power up */ + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + + + /* delays for the supply output is stable*/ + for ( i = 0; i < 0x80000; i++ ); + + /* During identification phase, the clock should be less than + 400Khz. Once we pass this phase, the normal clock can be set up + to 25Mhz on SD card and 20Mhz on MMC card. */ + MCI_Set_MCIClock(MCI_SLOW_RATE ); + + LPC_MCI->POWER |= 0x01; /* bit 1 is set already, from power up to power on */ + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + + NVIC_EnableIRQ(MCI_IRQn); + + MCI_CardInit(); + + /* During the initialization phase, to simplify the process, the CMD related + interrupts are disabled. The DATA related interrupts are enabled when + the FIFOs are used and just before WRITE_BLOCK READ_BLOCK cmds are issues, and + disabled after the data block has been written and read. Please also note, + before WRITE_BLOCK only TX related data interrupts are enabled, and before + READ_BLOCK only RX related data interrupts are enabled. */ + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Set output in open drain mode or pushpull mode + * + * @param[in] mode the mode going to set + * + * @return None + ***************************************************************************/ +void MCI_SetOutputMode(uint32_t mode) +{ + uint32_t i = 0; + if(mode == MCI_OUTPUT_MODE_OPENDRAIN) + { + /* Set Open Drain output control for MMC */ + LPC_MCI->POWER |= (1 << MCI_PWRCTRL_OPENDRAIN_POS) & MCI_PWRCTRL_BMASK; + } + else + { + /* Clear Open Drain output control for SD */ + LPC_MCI->POWER &= (~(1 << MCI_PWRCTRL_OPENDRAIN_POS) & MCI_PWRCTRL_BMASK); + } + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ +} + + +/************************************************************************//** + * @brief The routine is used to send a CMD to the card + * + * @param[in] CmdIndex the command to be sent to cards + * + * @param[in] Argument the argument follows the command + * + * @param[in] ExpectResp the response type for the command. They may be: + * - EXPECT_NO_RESP: means no response required + * - EXPECT_SHORT_RESP: means a response in a word needed + * - EXPECT_LONG_RESP: means a response in 4 words needed + * + * @param[in] AllowTimeout allow timeout the command or not + * + * @return None + ***************************************************************************/ +void MCI_SendCmd(st_Mci_CmdInfo* pCmdIf) +{ + volatile uint32_t i; + uint32_t CmdData = 0; + uint32_t CmdStatus; + + uint32_t CmdIndex = pCmdIf->CmdIndex; + uint32_t Argument = pCmdIf->Argument; + uint32_t ExpectResp = pCmdIf->ExpectResp; + uint32_t AllowTimeout = pCmdIf->AllowTimeout; + + /* the command engine must be disabled when we modify the argument + or the peripheral resends */ + while ( (CmdStatus = LPC_MCI->STATUS) & MCI_CMD_ACTIVE ) /* Command in progress. */ + { + LPC_MCI->COMMAND = 0; + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + LPC_MCI->CLEAR = CmdStatus | MCI_CMD_ACTIVE; + } + + + /*set the command details, the CmdIndex should 0 through 0x3F only */ + CmdData |= (CmdIndex & 0x3F); /* bit 0 through 5 only */ + + if ( ExpectResp == EXPECT_NO_RESP ) /* no response */ + { + CmdData &= ~((1 << 6) | (1 << 7)); /* Clear long response bit as well */ + } + else if ( ExpectResp == EXPECT_SHORT_RESP ) /* expect short response */ + { + CmdData |= (1 << 6); + } + else if ( ExpectResp == EXPECT_LONG_RESP ) /* expect long response */ + { + CmdData |= (1 << 6) | (1 << 7); + } + + if ( AllowTimeout == ALLOW_CMD_TIMER ) /* allow timeout or not */ + { + CmdData &= ~ MCI_DISABLE_CMD_TIMER; + } + else + { + CmdData |= MCI_DISABLE_CMD_TIMER; + } + + /*send the command*/ + CmdData |= (1 << 10); /* This bit needs to be set last. */ + + // clear status register + LPC_MCI->CLEAR = 0x7FF; + + LPC_MCI->ARGUMENT = Argument; /* Set the argument first, finally command */ + + LPC_MCI->COMMAND = CmdData; + + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + + // Wait until command is processed + while(!LPC_MCI->STATUS); + + // Wait until command sent + while(LPC_MCI->STATUS & MCI_CMD_ACTIVE); + + return; +} + + +/************************************************************************//** + * @brief The routine is to get the reponse from card after commands. + * This function is always used in pair of MCI_SendCmd() func + * + * @param[in] ExpectCmdData specify the command of which the data will be + * retrieved. This field should be the same with CmdIndex of + * MCI_SendCmd() function. + * + * @param[in] ExpectResp the response type for the command. They may be: + * - EXPECT_NO_RESP: means no response required + * - EXPECT_SHORT_RESP: means a response in a word needed + * - EXPECT_LONG_RESP: means a response in 4 words needed + * + * @param[out] CmdResp the buffer stored the data replied from cards + * + * @return MCI_FUNC_OK in case of success + ***************************************************************************/ +int32_t MCI_GetCmdResp(uint32_t ExpectCmdData, uint32_t ExpectResp, uint32_t *CmdResp) +{ + uint32_t CmdRespStatus = 0; + uint32_t LastCmdIndex; + uint32_t i = 0; + + if ( ExpectResp == EXPECT_NO_RESP ) + { + return MCI_FUNC_OK; + } + + while (1) + { + // Get the status of the component + CmdRespStatus = LPC_MCI->STATUS; + + if ( CmdRespStatus & (MCI_CMD_TIMEOUT) ) + { + LPC_MCI->CLEAR = CmdRespStatus | MCI_CMD_TIMEOUT; + + LPC_MCI->COMMAND = 0; + LPC_MCI->ARGUMENT = 0xFFFFFFFF; + + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + + return (CmdRespStatus); + } + + if ( CmdRespStatus & MCI_CMD_CRC_FAIL ) + { + LPC_MCI->CLEAR = CmdRespStatus | MCI_CMD_CRC_FAIL; + LastCmdIndex = LPC_MCI->COMMAND & 0x003F; + + if ( (LastCmdIndex == CMD1_SEND_OP_COND) || (LastCmdIndex == ACMD41_SEND_APP_OP_COND) + || (LastCmdIndex == CMD12_STOP_TRANSMISSION) ) + { + LPC_MCI->COMMAND = 0; + LPC_MCI->ARGUMENT = 0xFFFFFFFF; + for ( i = 0; i < 0x10; i++ ); /* delay 3MCLK + 2PCLK */ + break; /* ignore CRC error if it's a resp for SEND_OP_COND + or STOP_TRANSMISSION. */ + } + else + { + return (CmdRespStatus); + } + } + else if (CmdRespStatus & MCI_CMD_RESP_END) + { + LPC_MCI->CLEAR = CmdRespStatus | MCI_CMD_RESP_END; + break; /* cmd response is received, expecting response */ + } + + } + + if ((LPC_MCI->RESP_CMD & 0x3F) != ExpectCmdData) + { + /* If the response is not R1, in the response field, the Expected Cmd data + won't be the same as the CMD data in SendCmd(). Below four cmds have + R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same + as the Expected or not. */ + if ((ExpectCmdData != CMD1_SEND_OP_COND) && (ExpectCmdData != ACMD41_SEND_APP_OP_COND) + && (ExpectCmdData != CMD2_ALL_SEND_CID) && (ExpectCmdData != CMD9_SEND_CSD)) + { + CmdRespStatus = INVALID_RESPONSE; /* Reuse error status */ + return (INVALID_RESPONSE); + } + } + + /* Read MCI_RESP0 register assuming it's not long response. */ + if (CmdResp != NULL) + { + if (ExpectResp == EXPECT_SHORT_RESP) + { + *(CmdResp + 0) = LPC_MCI->RESP0; + } + else if (ExpectResp == EXPECT_LONG_RESP) + { + *(CmdResp + 0) = LPC_MCI->RESP0; + *(CmdResp + 1) = LPC_MCI->RESP1; + *(CmdResp + 2) = LPC_MCI->RESP2; + *(CmdResp + 3) = LPC_MCI->RESP3; + } + } + + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief The routine is to send command to cards then get back the + * reponses (if required). + * + * @param[in] CmdIndex the command to be sent to cards + * + * @param[in] Argument the argument follows the command + * + * @param[in] ExpectResp the response type for the command. They may be: + * - EXPECT_NO_RESP: means no response required + * - EXPECT_SHORT_RESP: means a response in a word needed + * - EXPECT_LONG_RESP: means a response in 4 words needed + * + * @param[out] CmdResp the buffer stored the data replied from cards + * + * @param[in] AllowTimeout allow timeout the command or not + * + * @return MCI_FUNC_OK in case of success + ***************************************************************************/ +int32_t MCI_CmdResp(st_Mci_CmdInfo* pCmdIf) +{ + int32_t respStatus; + uint32_t CmdIndex = pCmdIf->CmdIndex; + uint32_t ExpectResp = pCmdIf->ExpectResp; + uint32_t *CmdResp = pCmdIf->CmdResp; + + + MCI_SendCmd(pCmdIf); + + if((CmdResp != NULL) || (ExpectResp != EXPECT_NO_RESP)) + { + respStatus = MCI_GetCmdResp(CmdIndex, ExpectResp, CmdResp); + } + else + { + respStatus = MCI_FUNC_BAD_PARAMETERS; + } + + return respStatus; +} + + +/************************************************************************//** + * @brief To reset the card, the CMD0 is sent and then the card is put + * in idle state. This is the very first command to be sent to + * initialize either MMC or SD card. + * + * @param None + * + * @return Always MCI_FUNC_OK + ***************************************************************************/ +int32_t MCI_CardReset(void) +{ + st_Mci_CmdInfo cmdIf; + /* Because CMD0 command to put the device to idle state does not need response + since, it's only sending commad */ + cmdIf.CmdIndex = CMD0_GO_IDLE_STATE; + cmdIf.Argument = 0x00000000; + cmdIf.ExpectResp = EXPECT_NO_RESP; + cmdIf.AllowTimeout = 0; + cmdIf.CmdResp = 0; + MCI_SendCmd(&cmdIf); + + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Send CMD1 (SEND_OP_COND) to card. + * + * @param None + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_Cmd_SendOpCond( void ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + retryCount = 0x200; /* reset retry counter */ + + cmdIf.CmdIndex = CMD1_SEND_OP_COND; + cmdIf.Argument = OCR_INDEX; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + /* continuously sends until the busy bit is cleared */ + while ( retryCount > 0 ) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus & MCI_CMD_TIMEOUT) + { + retval = MCI_FUNC_TIMEOUT; + } + else if ((respValue[0] & 0x80000000) == 0) + { + //The card has not finished the power up routine + retval = MCI_FUNC_BUS_NOT_IDLE; + } + else + { + retval = MCI_FUNC_OK; + break; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return(retval); +} + + +/************************************************************************//** + * @brief Send CMD8 (SEND_IF_COND) for interface condition to card. + * + * @param None + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_Cmd_SendIfCond(void) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t CmdArgument; + uint32_t respStatus; + uint32_t respValue[4]; + + int32_t retval = MCI_FUNC_FAILED; + + uint8_t voltageSupplied = MCI_CMD8_VOLATAGESUPPLIED_27_36;//in range 2.7-3.6V + uint8_t checkPattern = 0xAA; + st_Mci_CmdInfo cmdIf; + + CmdArgument = (voltageSupplied << MCI_CMD8_VOLTAGESUPPLIED_POS) | (checkPattern << MCI_CMD8_CHECKPATTERN_POS); + + retryCount = 20; + + cmdIf.CmdIndex = CMD8_SEND_IF_COND; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus & MCI_CMD_TIMEOUT) + { + //Consider as no response + retval = MCI_FUNC_TIMEOUT; + } + else if (((respValue[0]>>MCI_CMD8_CHECKPATTERN_POS) & MCI_CMD8_CHECKPATTERN_BMASK) != checkPattern) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else if (((respValue[0] >> MCI_CMD8_VOLTAGESUPPLIED_POS) & MCI_CMD8_VOLTAGESUPPLIED_BMASK) + != voltageSupplied) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + return MCI_FUNC_OK; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Send CMD55 (APP_CMD) to indicate to the card that the next + * command is an application specific command rather than a + * standard command. Before an ACMD, call this routine first + * + * @param None + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_Cmd_SendACMD( void ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t CmdArgument; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + CmdArgument = CardRCA; /* Use the address from SET_RELATIVE_ADDR cmd */ + } + else /* if MMC or unknown card type, use 0x0. */ + { + CmdArgument = 0x00000000; + } + + retryCount = 20; + + cmdIf.CmdIndex = CMD55_APP_CMD; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus != 0) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ACMD_ENABLE) + { + retval = MCI_FUNC_OK; + break; + } + else + { + retval = MCI_FUNC_NOT_READY; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Send ACMD41 (SEND_APP_OP_COND) to Host Capacity Support (HCS) + * information and asks the accessed card to send its operating + * condition (OCR). + * + * @param[in] hcsVal input the Host Capacity Support + * + * @return MCI_FUNC_OK if all success + * + * @note If SEND_APP_OP_COND is timeout, the card in the slot is not MMC + * type, try this combination to see if we can communicate with + * a SD type. + ****************************************************************************/ +int32_t MCI_Acmd_SendOpCond(uint8_t hcsVal) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus, argument; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + + int32_t retval = MCI_FUNC_FAILED; + + argument = OCR_INDEX | (hcsVal << MCI_ACMD41_HCS_POS); + + /* timeout on SEND_OP_COND command on MMC, now, try SEND_APP_OP_COND + command to SD */ + retryCount = 0x2000; /* reset retry counter */ + + cmdIf.CmdIndex = ACMD41_SEND_APP_OP_COND; + cmdIf.Argument = argument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + + /* Clear Open Drain output control for SD */ + MCI_SetOutputMode(MCI_OUTPUT_MODE_PUSHPULL); + + /* The host repeatedly issues ACMD41 for at least 1 second or */ + /* until the busy bit are set to 1 */ + while ( retryCount > 0 ) + { + if ((retval = MCI_Cmd_SendACMD()) == MCI_FUNC_OK) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus & MCI_CMD_TIMEOUT) + { + retval = MCI_FUNC_TIMEOUT; + } + else if (!(respValue[0] & 0x80000000)) + { + retval = MCI_FUNC_BUS_NOT_IDLE; + } + else + { + CCS = (respValue[0]&(1<<30)) ? 1:0; + retval = MCI_FUNC_OK; + break; + } + } + else /* The command isn't accepted by the card.*/ + { + return retval; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + +/************************************************************************//** + * @brief Do initialization for the card in the slot + * + * @details Try CMD1 first for MMC, if it's timeout, try CMD55 + * and CMD41 for SD, if both failed, initialization faliure, + * bailout with unknown card type. Otherwise, return the + * card type, either MMC or SD. <<>> + * + * This is followed Figure 4-2: Card Initialization and + * Identification Flow (SD mode) in Physical Layer Simplified + * Specification Version 2.00 document + * + * @param None + * + * @return MCI_FUNC_OK if success + ****************************************************************************/ +int32_t MCI_CardInit( void ) +{ + volatile uint32_t i; + int32_t retval = MCI_FUNC_FAILED; + + MCI_CardType = MCI_CARD_UNKNOWN; + + if (MCI_CardReset() != MCI_FUNC_OK) + { + return MCI_FUNC_FAILED; + } + + /* Clear Open Drain output control for SD */ + MCI_SetOutputMode(MCI_OUTPUT_MODE_PUSHPULL); + + for ( i = 0; i < 0x3000; i++ ); + + retval = MCI_Cmd_SendIfCond(); + + if(retval == MCI_FUNC_BAD_PARAMETERS) + { + //Unknow card is unusable + return retval; + } + + if(retval == MCI_FUNC_OK) /* Ver2.00 or later*/ + { + //Check in case of High Capacity Supporting Host + if ((retval = MCI_Acmd_SendOpCond(1)) == MCI_FUNC_OK) + { + MCI_CardType = MCI_SDSC_V2_CARD;//SDSC + + if(CCS ) + { + MCI_CardType = MCI_SDHC_SDXC_CARD;//SDHC or SDXC + } + + return MCI_FUNC_OK; /* Found the card, it's a hD */ + } + } + + if(retval != MCI_FUNC_OK) /* voltage mismatch (ver2.00)or ver1.X SD Card or not SD Card*/ + { + + //Check in case of Standard Capacity Supporting Host + if ((retval = MCI_Acmd_SendOpCond(0)) == MCI_FUNC_OK) + { + MCI_CardType = MCI_SDSC_V1_CARD;//Support Standard Capacity only + + return MCI_FUNC_OK; /* Found the card, it's a SD */ + } + } + + if(retval != MCI_FUNC_OK) + { + /* Set Open Drain output control for MMC */ + MCI_SetOutputMode(MCI_OUTPUT_MODE_OPENDRAIN); + + for ( i = 0; i < 0x3000; i++ ); + + /* Try CMD1 first for MMC, if it's timeout, try CMD55 and CMD41 for SD, + if both failed, initialization faIlure, bailout. */ + if (MCI_Cmd_SendOpCond() == MCI_FUNC_OK) + { + MCI_CardType = MCI_MMC_CARD; + + return MCI_FUNC_OK; /* Found the card, it's a MMC */ + } + } + + /* tried both MMC and SD card, give up */ + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Get the type of card that is currently used in the slot + * + * @param None + * + * @return Card Type: MMC Card or SD card + ****************************************************************************/ +en_Mci_CardType MCI_GetCardType(void) +{ + return MCI_CardType; +} + + +/************************************************************************//** + * @brief Get the all the Identifier (CID) of the card by sending the + * CMD2 (ALL_SEND_CID) command. Then parse 4-byte data obtained + * from the card by the CID meaning. + * + * @param[out] cidValue the CID Result after parsing the data from the card + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_GetCID(st_Mci_CardId* cidValue) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + + /* This command is normally after CMD1(MMC) or ACMD41(SD). */ + retryCount = 0x200;// 0x20; /* reset retry counter */ + + cmdIf.CmdIndex = CMD2_ALL_SEND_CID; + cmdIf.Argument = 0; + cmdIf.ExpectResp = EXPECT_LONG_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + respStatus = MCI_CmdResp(&cmdIf); + + /* bit 0 and bit 2 must be zero, or it's timeout or CRC error */ + //if ((!(respStatus & MCI_CMD_TIMEOUT)) && (!(respStatus & MCI_CMD_CRC_FAIL))) + if (!(respStatus & MCI_CMD_TIMEOUT)) + { + // Parsing the data retrieved + if(cidValue != NULL) + { + cidValue->MID = (respValue[0] >> MCI_CID_MANUFACTURER_ID_WPOS) & MCI_CID_MANUFACTURER_ID_WBMASK; + + cidValue->OID = (respValue[0] >> MCI_CID_OEMAPPLICATION_ID_WPOS) & MCI_CID_OEMAPPLICATION_ID_WBMASK; + + cidValue->PNM_H = (respValue[0] >> MCI_CID_PRODUCTNAME_ID_H_WPOS) & MCI_CID_PRODUCTNAME_ID_H_WBMASK; + + cidValue->PNM_L = (respValue[1] >> MCI_CID_PRODUCTNAME_ID_L_WPOS) & MCI_CID_PRODUCTNAME_ID_L_WBMASK; + + cidValue->PRV = (respValue[2] >> MCI_CID_PRODUCTREVISION_ID_WPOS) & MCI_CID_PRODUCTREVISION_ID_WBMASK; + + cidValue->PSN = (((respValue[2] >> MCI_CID_PRODUCTSERIALNUM_ID_H_WPOS) & MCI_CID_PRODUCTSERIALNUM_ID_H_WBMASK) << 8) + | ((respValue[3] >> MCI_CID_PRODUCTSERIALNUM_ID_L_WPOS) & MCI_CID_PRODUCTSERIALNUM_ID_L_WBMASK); + + cidValue->reserved = (respValue[3] >> MCI_CID_RESERVED_ID_WPOS) & MCI_CID_RESERVED_ID_WBMASK; + + cidValue->MDT = (respValue[3] >> MCI_CID_MANUFACTURINGDATE_ID_WPOS) & MCI_CID_MANUFACTURINGDATE_ID_WBMASK; + + cidValue->CRC = (respValue[3] >> MCI_CID_CHECKSUM_ID_WPOS) & MCI_CID_CHECKSUM_ID_WBMASK; + + cidValue->unused = (respValue[3] >> MCI_CID_UNUSED_ID_WPOS) & MCI_CID_UNUSED_ID_WBMASK; + + } + + return MCI_FUNC_OK; /* response is back and correct. */ + } + + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return MCI_FUNC_TIMEOUT; +} + + +/************************************************************************//** + * @brief Set the address for the card in the slot by sending CMD3 + * (SET_RELATIVE_ADDR) command. To get the address of the card + * currently in used, needs to call MCI_GetCardAddress() + * + * @param None + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_SetCardAddress( void ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue; + uint32_t CmdArgument; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + /* If it's a SD card, SET_RELATIVE_ADDR is to get the address + from the card and use this value in RCA, if it's a MMC, set default + RCA addr. 0x00010000. */ + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + CmdArgument = 0; + } + else /* If it's unknown or MMC_CARD, fix the RCA address */ + { + CmdArgument = 0x00010000; + } + + retryCount = 0x20; /* reset retry counter */ + cmdIf.CmdIndex = CMD3_SET_RELATIVE_ADDR; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = &respValue; + while ( retryCount > 0 ) + { + /* Send CMD3 command repeatedly until the response is back correctly */ + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus & MCI_CMD_TIMEOUT) + { + retval = MCI_FUNC_TIMEOUT; + } + else if(!((respValue >> RCA_RES_CARD_STATUS_POS)& CARD_STATUS_READY_FOR_DATA)) + { + retval = MCI_FUNC_NOT_READY; + } + else if((CARDSTATEOF(respValue) != MCI_CARDSTATE_IDENDTIFIED)) + { + retval = MCI_FUNC_ERR_STATE; + } + else + { + CardRCA = (respValue >> RCA_RES_NEW_PUBLISHED_RCA_POS) & RCA_RES_NEW_PUBLISHED_RCA_MASK; /* Save the RCA value from SD card */ + + CardRCA <<= RCA_ARGUMENT_POS; + + MCI_SetOutputMode(MCI_OUTPUT_MODE_PUSHPULL); + + return (MCI_FUNC_OK); /* response is back and correct. */ + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Get the address for the card in the slot + * + * @param None + * + * @return MCI_FUNC_OK if all success + * + * @note This function must be called after MCI_SetCardAddress() executing + ****************************************************************************/ +uint32_t MCI_GetCardAddress(void) +{ + return CardRCA; +} + + +/************************************************************************//** + * @brief Get the Card-Specific Data of in-slot card by sending CMD9 + * (SEND_CSD) command + * + * @param[out] csdVal a buffer stored the value of CSD obtained from the card + * + * @return MCI_FUNC_OK if all success + * + * @note CMD9 (SEND_CSD) command should be sent only at standby state + * (STBY) after CMD3 + ****************************************************************************/ +int32_t MCI_GetCSD(uint32_t* csdVal) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + uint32_t CmdArgument; + st_Mci_CmdInfo cmdIf; + + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + CmdArgument = CardRCA; + } + else /* if MMC or unknown card type, use default RCA addr. */ + { + CmdArgument = 0x00010000; + } + + retryCount = 0x20; + cmdIf.CmdIndex = CMD9_SEND_CSD; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_LONG_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* Check current status */ + if(((MCI_CheckStatus(CARD_STATE_STBY) != MCI_FUNC_OK))) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if ( !respStatus ) + { + if(csdVal != NULL) + { + csdVal[0] = respValue[0]; + csdVal[1] = respValue[1]; + csdVal[2] = respValue[2]; + csdVal[3] = respValue[3]; + } + + return (MCI_FUNC_OK); + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return (MCI_FUNC_FAILED); +} + + +/************************************************************************//** + * @brief Select the card by the specified address. This is done by sending + * out the CMD7 with the address argument to needed card + * + * @param None + * + * @return MCI_FUNC_OK if all success + * + * @note CMD7 (SELECT_CARD) command should be sent after CMD9 ((SEND_CSD). + * The state will be inter-changed between STBY to TRANS by this + * CMD7 command + ****************************************************************************/ +int32_t MCI_Cmd_SelectCard( void ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + uint32_t CmdArgument; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + CmdArgument = CardRCA; + } + else /* if MMC or unknown card type, use default RCA addr. */ + { + CmdArgument = 0x00010000; + } + + retryCount = 0x20; + cmdIf.CmdIndex = CMD7_SELECT_CARD; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* Check current status */ + if(((MCI_CheckStatus(CARD_STATE_STBY) != MCI_FUNC_OK)) && + (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_DATA) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_PRG) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_DIS) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + if(((MCI_CheckStatus(CARD_STATE_STBY) != MCI_FUNC_OK)) && + (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_PRG) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_DIS) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + return MCI_FUNC_OK; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Get the status of the card. The return is from the card. + * By sending CMD13 (SEND_STATUS), the status of the card + * will be responded from card addressed + * + * @param[out] cardStatus the status returned from the card + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_GetCardStatus(int32_t* cardStatus) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + uint32_t CmdArgument; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + if(cardStatus == NULL) + return MCI_FUNC_OK; + + if ((MCI_CardType == MCI_SDSC_V1_CARD) || + (MCI_CardType == MCI_SDSC_V2_CARD) || + (MCI_CardType == MCI_SDHC_SDXC_CARD)) + { + CmdArgument = CardRCA; + } + else /* if MMC or unknown card type, use default RCA addr. */ + { + CmdArgument = 0x00010000; + } + + retryCount = 0x20; + cmdIf.CmdIndex = CMD13_SEND_STATUS; + cmdIf.Argument = CmdArgument; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) /* only retry if sending command failed */ + { + retval = MCI_FUNC_FAILED; + } + else + { + *cardStatus = respValue[0]; + + return MCI_FUNC_OK; + } + + retryCount--; + for ( i = 0; i < 0x10; i++ ); + } + + return retval; +} + +/************************************************************************//** + * @brief Set the length for the blocks in the next action on data + * manipulation (as read, write, erase). This function is to + * send CMD16 (SET_BLOCK_LEN) to cards. + * + * @param[in] blockLength the value for the length of block will be handled + * + * @return MCI_FUNC_OK if all success + * + * @note CMD16 command should be sent after the card is selected by CMD7 + * (SELECT_CARD). + * In the case of SDHC and SDXC Cards, block length set by CMD16 command doen't + * affect memory read and write commands. Always 512 Bytes fixed block length is + * used. This command is effective for LOCK_UNLOCK command.. + ****************************************************************************/ +int32_t MCI_SetBlockLen(uint32_t blockLength) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + retryCount = 0x20; + cmdIf.CmdIndex = CMD16_SET_BLOCK_LEN; + cmdIf.Argument = blockLength; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* Check current status */ + if((MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK) ) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + return MCI_CheckStatus(CARD_STATE_TRAN); + } + + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Set bus-width (1 bit or 4 bit) to work with the card by command + * CMD6 (SET_ACMD_BUS_WIDTH). + * + * @param[in] buswidth The value represented for bus-width + * - 0b00: 1-bit bus-width + * - 0b10: 4-bit bus-width + * + * @return MCI_FUNC_OK if all success + * + * @note + * - If SD card is currently in used, it's possible to enable 4-bit + * bus-width instead of 1-bit to speed up. + * - This command can only be transferred during TRANS state. + * - Since, it's a ACMD, CMD55 (APP_CMD) needs to be sent out first + ****************************************************************************/ +int32_t MCI_Acmd_SendBusWidth( uint32_t buswidth ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + retryCount = 0x20; /* reset retry counter */ + cmdIf.CmdIndex = ACMD6_SET_BUS_WIDTH; + cmdIf.Argument = buswidth; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* The card must be in tran state in order to change the bus width */ + retval = MCI_CheckStatus(CARD_STATE_TRAN); + if(retval!= MCI_FUNC_OK) + return retval; + + if (MCI_Cmd_SendACMD() == MCI_FUNC_OK) + { + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + return MCI_CheckStatus(CARD_STATE_TRAN); + } + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Get the state of data transfer to see if it is ended or not + * + * @param None + * + * @return Transfer state (stored by Mci_Data_Xfer_End variable) + ****************************************************************************/ +uint32_t MCI_GetDataXferEndState(void) +{ + return Mci_Data_Xfer_End; +} +/************************************************************************//** + * @brief Get the error state of the lastest data transfer + * + * @param None + * + * @return Error state (stored by Mci_Data_Xfer_ERR variable) + ****************************************************************************/ +uint32_t MCI_GetXferErrState(void) +{ + return Mci_Data_Xfer_ERR; +} + +/************************************************************************//** + * @brief Stop the current transmission on the bus by sending command CMD12 + * (STOP_TRANSMISSION). In this case, the card may be in a unknown + * state. So that it need a warm reset for normal operation. + * + * @param[in] None + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_Cmd_StopTransmission( void ) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + /* do nothing when the card is in tran state */ + if(MCI_CheckStatus(CARD_STATE_TRAN) == MCI_FUNC_OK) + { + return MCI_FUNC_OK; + } + + retryCount = 0x20; + cmdIf.CmdIndex = CMD12_STOP_TRANSMISSION; + cmdIf.Argument = 0x00000000; + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* Check current status */ + if((MCI_CheckStatus(CARD_STATE_DATA) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_RCV) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + if((MCI_CheckStatus(CARD_STATE_PRG) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + return MCI_FUNC_OK; + } + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + } + + return retval; +} + + +/************************************************************************//** + * @brief Write blocks to card by sending command CMD24 (WRITE_BLOCK) or + * command CMD25 (WRITE_MULTIPLE_BLOCK) followed by the blocks of + * data to be written. + * + * @param[in] blockNum The block number to start writting + * + * @param[in] numOfBlock Determine how many blocks will be written (from the + * starting block) + * + * @return MCI_FUNC_OK if all success + * + * @note These commands should be sent in TRANS state. + ****************************************************************************/ +int32_t MCI_Cmd_WriteBlock(uint32_t blockNum, uint32_t numOfBlock) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + st_Mci_CmdInfo cmdIf; + uint32_t commandID; + + int32_t retval = MCI_FUNC_FAILED; + + if (numOfBlock > 1) + { + commandID = CMD25_WRITE_MULTIPLE_BLOCK; + } + else + { + commandID = CMD24_WRITE_BLOCK; + } + + retryCount = 0x20; + cmdIf.CmdIndex = commandID; + if (MCI_CardType == MCI_SDHC_SDXC_CARD) + { + cmdIf.Argument = blockNum; /* Block Address */ + } + else + { + cmdIf.Argument = blockNum * BLOCK_LENGTH; /* Byte Address */ + } + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + + while ( retryCount > 0 ) + { + /* Check current status */ + if((MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + if((MCI_CheckStatus(CARD_STATE_RCV) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + return MCI_FUNC_OK; + } + + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + + } + + return retval; /* Fatal error */ +} + + + + +/************************************************************************//** + * @brief Read blocks to card by sending CMD17 (READ_SINGLE_BLOCK) or + * CMD18 (READ_MULTIPLE_BLOCK) commands followed by the blocks of + * data to be read. + * + * @param[in] blockNum The block number to start reading + * + * @param[in] numOfBlock Determine how many blocks will be read (from the + * starting block) + * + * @return MCI_FUNC_OK if all success + * + * @note These commands should be sent in TRANS state. + ****************************************************************************/ +int32_t MCI_Cmd_ReadBlock(uint32_t blockNum, uint32_t numOfBlock) +{ + volatile uint32_t i; + uint32_t retryCount; + uint32_t respStatus; + uint32_t respValue[4]; + uint32_t commandID; + st_Mci_CmdInfo cmdIf; + int32_t retval = MCI_FUNC_FAILED; + + // To Do: Read Multi-Block + if (numOfBlock > 1) + commandID = CMD18_READ_MULTIPLE_BLOCK; + else + commandID = CMD17_READ_SINGLE_BLOCK; + + retryCount = 0x20; + cmdIf.CmdIndex = commandID; + if (MCI_CardType == MCI_SDHC_SDXC_CARD) + { + cmdIf.Argument = blockNum; /* Block Address */ + } + else + { + cmdIf.Argument = blockNum * BLOCK_LENGTH; /* Byte Address */ + } + cmdIf.ExpectResp = EXPECT_SHORT_RESP; + cmdIf.AllowTimeout = ALLOW_CMD_TIMER; + cmdIf.CmdResp = (uint32_t *)&respValue[0]; + while ( retryCount > 0 ) + { + /* Check current status */ + if((MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + + respStatus = MCI_CmdResp(&cmdIf); + + if(respStatus) + { + retval = MCI_FUNC_FAILED; + } + else if (respValue[0] & CARD_STATUS_ERR_MASK) + { + return MCI_FUNC_BAD_PARAMETERS; + } + else + { + if((MCI_CheckStatus(CARD_STATE_DATA) != MCI_FUNC_OK) && + (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK)) + return MCI_FUNC_ERR_STATE; + return MCI_FUNC_OK; + } + + + for ( i = 0; i < 0x20; i++ ); + + retryCount--; + + } + + return retval; +} + + +/************************************************************************//** + * @brief Write data at a specific address to starting block with number + * of blocks will be written from first block + * @details + * - At preparation + * - Set MCI data control register, data length and data timeout + * - Send CMD24 (WRITE_BLOCK) or CMD25 (WRITE_MULTIPLE_BLOCK) + * commands to card + * - Enable interupt for MCI component + * - At completion + * - TX_ACTIVE interrupt is occured + * - Write data to FIFO register continuously until the data block + * length is reached + * + * @param[in] *memblock The pointer to location stored required data to be + * written to card + * + * @param[in] blockNum The block number to start writting + * + * @param[in] numOfBlock Determine how many blocks will be written (from the + * starting block) + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_WriteBlock(volatile uint8_t* memblock, uint32_t blockNum, uint32_t numOfBlock) +{ + volatile uint32_t i; + uint32_t DataCtrl = 0; + + if(BLOCK_LENGTH*numOfBlock > DATA_RW_MAX_LEN) + return MCI_FUNC_BAD_PARAMETERS; + + dataSrcBlock = memblock; + + LPC_MCI->CLEAR = 0x7FF; + + LPC_MCI->DATACTRL = 0; + + for ( i = 0; i < 0x10; i++ ); + + /* Wait the SD Card enters to TRANS state. */ + if (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK) + return MCI_FUNC_ERR_STATE; + + LPC_MCI->DATATMR = DATA_TIMER_VALUE_W; + + LPC_MCI->DATALEN = BLOCK_LENGTH*numOfBlock; + + Mci_Data_Xfer_End = 1; + Mci_Data_Xfer_ERR = 0; + fifo_plane = 0; + + txBlockCnt = 0; + + MCI_TXEnable(); + + if (MCI_Cmd_WriteBlock(blockNum, numOfBlock) != MCI_FUNC_OK) + { + return ( MCI_FUNC_FAILED ); + } + + //for(blockCnt = 0; blockCnt < numOfBlock; blockCnt++) + { +#if MCI_DMA_ENABLED + MCI_SettingDma((uint8_t*) dataSrcBlock, MCI_DMA_WRITE_CHANNEL, GPDMA_TRANSFERTYPE_M2P_DEST_CTRL); + + /* Write, block transfer, DMA, and data length */ + DataCtrl |= MCI_DATACTRL_ENABLE | MCI_DATACTRL_DIR_TO_CARD + | MCI_DATACTRL_DMA_ENABLE | MCI_DTATCTRL_BLOCKSIZE(DATA_BLOCK_LEN); +#else + /* Write, block transfer, and data length */ + DataCtrl |= MCI_DATACTRL_ENABLE | MCI_DATACTRL_DIR_TO_CARD | MCI_DTATCTRL_BLOCKSIZE(DATA_BLOCK_LEN); +#endif + } + + LPC_MCI->DATACTRL = DataCtrl; + + for ( i = 0; i < 0x10; i++ ); + + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Read data at a specific address to starting block with number + * of blocks will be read from first block + * + * @details + * - At preparation + * - Set MCI data control register, data length and data timeout + * - Send CMD17 (READ_SINGLE_BLOCK) or CMD18 (READ_MULTIPLE_BLOCK) + * commands to card + * - Enable interupt for MCI component + * - At completion + * - RX_ACTIVE interrupt is occured + * - Read data from FIFO register continuously until the data block + * length is reached to retrieve needed data + * + * @param[in] *destBlock The pointer to location will captured data read + * from card + * + * @param[in] blockNum The block number to start reading + * + * @param[in] numOfBlock Determine how many blocks will be read (from the + * starting block) + * + * @return MCI_FUNC_OK if all success + ****************************************************************************/ +int32_t MCI_ReadBlock(volatile uint8_t* destBlock, uint32_t blockNum, uint32_t numOfBlock) +{ + volatile uint32_t i; + uint32_t DataCtrl = 0; + + if(BLOCK_LENGTH*numOfBlock > DATA_RW_MAX_LEN) + return MCI_FUNC_BAD_PARAMETERS; + + dataDestBlock = destBlock; + + LPC_MCI->CLEAR = 0x7FF; + + LPC_MCI->DATACTRL = 0; + + for ( i = 0; i < 0x10; i++ ); + + /* Wait the SD Card enters to TRANS state. */ + if (MCI_CheckStatus(CARD_STATE_TRAN) != MCI_FUNC_OK) + return MCI_FUNC_ERR_STATE; + + MCI_RXEnable(); + + LPC_MCI->DATATMR = DATA_TIMER_VALUE_R; + + LPC_MCI->DATALEN = BLOCK_LENGTH*numOfBlock; + + Mci_Data_Xfer_End = 1; + Mci_Data_Xfer_ERR = 0; + rxBlockCnt = 0; + fifo_plane = 0; + + + // Start data engine on READ before command to avoid overflow of the FIFO. + { +#if MCI_DMA_ENABLED + MCI_SettingDma((uint8_t*) dataDestBlock, MCI_DMA_READ_CHANNEL, GPDMA_TRANSFERTYPE_P2M_SRC_CTRL); + + /* Write, block transfer, DMA, and data length */ + DataCtrl |= MCI_DATACTRL_ENABLE | MCI_DATACTRL_DIR_FROM_CARD + | MCI_DATACTRL_DMA_ENABLE | MCI_DTATCTRL_BLOCKSIZE(DATA_BLOCK_LEN); +#else + //Retrieving the result after reading the card is done by the FIFO handling for interrupt + + /* Read, enable, block transfer, and data length */ + DataCtrl |= MCI_DATACTRL_ENABLE | MCI_DATACTRL_DIR_FROM_CARD | MCI_DTATCTRL_BLOCKSIZE(DATA_BLOCK_LEN); + +#endif + } + + LPC_MCI->DATACTRL = DataCtrl; + + for ( i = 0; i < 0x10; i++ ); + + if ( MCI_Cmd_ReadBlock(blockNum, numOfBlock) != MCI_FUNC_OK ) + { + return MCI_FUNC_FAILED; + } + + return MCI_FUNC_OK; +} + + +/************************************************************************//** + * @brief Turn off the MCI power by disabling the Power Register for MCI + * + * @param None + * + * @return None + ****************************************************************************/ +void MCI_PowerOff(void) +{ + volatile uint32_t i; + + LPC_MCI->POWER = 0; + + for (i = 0; i < 0x100; i++); + + return; +} + + +/** + * @} + */ + +#endif /*_MCI*/ + +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_mcpwm.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_mcpwm.c new file mode 100644 index 0000000000000000000000000000000000000000..479ec4d9a4f1544f8fe2d763fe63986b2d97a446 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_mcpwm.c @@ -0,0 +1,573 @@ +/********************************************************************** +* $Id$ lpc_mcpwm.c 2011-06-02 +*//** +* @file lpc_mcpwm.c +* @brief Contains all functions support for Motor Control PWM +* firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup MCPWM + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _MCPWM + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_mcpwm.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup MCPWM_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Initializes the MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected, + * Should be: LPC_MCPWM + * @return None + **********************************************************************/ +void MCPWM_Init(LPC_MCPWM_TypeDef *MCPWMx) +{ + /* Turn On MCPWM PCLK */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCMCPWM, ENABLE); + + MCPWMx->CAP_CLR = MCPWM_CAPCLR_CAP(0) | MCPWM_CAPCLR_CAP(1) | MCPWM_CAPCLR_CAP(2); + + MCPWMx->INTF_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \ + | MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \ + | MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2); + + MCPWMx->INTEN_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \ + | MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \ + | MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2); +} + + +/*********************************************************************//** + * @brief Configures each channel in MCPWM peripheral according to the + * specified parameters in the MCPWM_CHANNEL_CFG_Type. + * @param[in] MCPWMx Motor Control PWM peripheral selected + * should be: LPC_MCPWM + * @param[in] channelNum Channel number, should be: 0..2. + * @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure +* that contains the configuration information for the +* specified MCPWM channel. + * @return None + **********************************************************************/ +void MCPWM_ConfigChannel(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CHANNEL_CFG_Type * channelSetup) +{ + if (channelNum < MCPWM_MAX_CHANNEL) + { + if (channelNum == MCPWM_CHANNEL_0) + { + MCPWMx->TC0 = channelSetup->channelTimercounterValue; + MCPWMx->LIM0 = channelSetup->channelPeriodValue; + MCPWMx->MAT0 = channelSetup->channelPulsewidthValue; + } + else if (channelNum == MCPWM_CHANNEL_1) + { + MCPWMx->TC1 = channelSetup->channelTimercounterValue; + MCPWMx->LIM1 = channelSetup->channelPeriodValue; + MCPWMx->MAT1 = channelSetup->channelPulsewidthValue; + } + else if (channelNum == MCPWM_CHANNEL_2) + { + MCPWMx->TC2 = channelSetup->channelTimercounterValue; + MCPWMx->LIM2 = channelSetup->channelPeriodValue; + MCPWMx->MAT2 = channelSetup->channelPulsewidthValue; + } + else + { + return; + } + + if (channelSetup->channelType == MCPWM_CHANNEL_CENTER_MODE) + { + MCPWMx->CON_SET = MCPWM_CON_CENTER(channelNum); + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_CENTER(channelNum); + } + + if (channelSetup->channelPolarity == MCPWM_CHANNEL_PASSIVE_HI) + { + MCPWMx->CON_SET = MCPWM_CON_POLAR(channelNum); + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_POLAR(channelNum); + } + + if (channelSetup->channelDeadtimeEnable == ENABLE) + { + MCPWMx->CON_SET = MCPWM_CON_DTE(channelNum); + + MCPWMx->DT &= ~(MCPWM_DT(channelNum, 0x3FF)); + + MCPWMx->DT |= MCPWM_DT(channelNum, channelSetup->channelDeadtimeValue); + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_DTE(channelNum); + } + + if (channelSetup->channelUpdateEnable == ENABLE) + { + MCPWMx->CON_CLR = MCPWM_CON_DISUP(channelNum); + } + else + { + MCPWMx->CON_SET = MCPWM_CON_DISUP(channelNum); + } + } +} + + +/*********************************************************************//** + * @brief Write to MCPWM shadow registers - Update the value for period + * and pulse width in MCPWM peripheral. + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] channelNum Channel Number, should be: 0..2. + * @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure +* that contains the configuration information for the +* specified MCPWM channel. + * @return None + **********************************************************************/ +void MCPWM_WriteToShadow(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CHANNEL_CFG_Type *channelSetup) +{ + if (channelNum == MCPWM_CHANNEL_0) + { + MCPWMx->LIM0 = channelSetup->channelPeriodValue; + MCPWMx->MAT0 = channelSetup->channelPulsewidthValue; + } + else if (channelNum == MCPWM_CHANNEL_1) + { + MCPWMx->LIM1 = channelSetup->channelPeriodValue; + MCPWMx->MAT1 = channelSetup->channelPulsewidthValue; + } + else if (channelNum == MCPWM_CHANNEL_2) + { + MCPWMx->LIM2 = channelSetup->channelPeriodValue; + MCPWMx->MAT2 = channelSetup->channelPulsewidthValue; + } +} + + + +/*********************************************************************//** + * @brief Configures capture function in MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] channelNum MCI (Motor Control Input pin) number + * Should be: 0..2 + * @param[in] captureConfig Pointer to a MCPWM_CAPTURE_CFG_Type structure +* that contains the configuration information for the +* specified MCPWM capture. + * @return + **********************************************************************/ +void MCPWM_ConfigCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CAPTURE_CFG_Type *captureConfig) +{ + if (channelNum < MCPWM_MAX_CHANNEL) + { + + if (captureConfig->captureFalling == ENABLE) + { + MCPWMx->CAPCON_SET = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum); + } + else + { + MCPWMx->CAPCON_CLR = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum); + } + + if (captureConfig->captureRising == ENABLE) + { + MCPWMx->CAPCON_SET = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum); + } + else + { + MCPWMx->CAPCON_CLR = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum); + } + + if (captureConfig->timerReset == ENABLE) + { + MCPWMx->CAPCON_SET = MCPWM_CAPCON_RT(captureConfig->captureChannel); + } + else + { + MCPWMx->CAPCON_CLR = MCPWM_CAPCON_RT(captureConfig->captureChannel); + } + + if (captureConfig->hnfEnable == ENABLE) + { + MCPWMx->CAPCON_SET = MCPWM_CAPCON_HNFCAP(channelNum); + } + else + { + MCPWMx->CAPCON_CLR = MCPWM_CAPCON_HNFCAP(channelNum); + } + } +} + + +/*********************************************************************//** + * @brief Clears current captured value in specified capture channel + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] captureChannel Capture channel number, should be: 0..2 + * @return None + **********************************************************************/ +void MCPWM_ClearCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel) +{ + MCPWMx->CAP_CLR = MCPWM_CAPCLR_CAP(captureChannel); +} + +/*********************************************************************//** + * @brief Get current captured value in specified capture channel + * @param[in] MCPWMx Motor Control PWM peripheral selected, + * Should be: LPC_MCPWM + * @param[in] captureChannel Capture channel number, should be: 0..2 + * @return None + **********************************************************************/ +uint32_t MCPWM_GetCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel) +{ + if (captureChannel == MCPWM_CHANNEL_0) + { + return (MCPWMx->CAP0); + } + else if (captureChannel == MCPWM_CHANNEL_1) + { + return (MCPWMx->CAP1); + } + else if (captureChannel == MCPWM_CHANNEL_2) + { + return (MCPWMx->CAP2); + } + return (0); +} + + +/*********************************************************************//** + * @brief Configures Count control in MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] channelNum Channel number, should be: 0..2 + * @param[in] countMode Count mode, should be: + * - ENABLE: Enables count mode. + * - DISABLE: Disable count mode, the channel is in timer mode. + * @param[in] countConfig Pointer to a MCPWM_COUNT_CFG_Type structure +* that contains the configuration information for the +* specified MCPWM count control. + * @return None + **********************************************************************/ +void MCPWM_CountConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + uint32_t countMode, MCPWM_COUNT_CFG_Type *countConfig) +{ + if (channelNum < MCPWM_MAX_CHANNEL) + { + if (countMode == ENABLE) + { + MCPWMx->CNTCON_SET = MCPWM_CNTCON_CNTR(channelNum); + + if (countConfig->countFalling == ENABLE) + { + MCPWMx->CNTCON_SET = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum); + } + else + { + MCPWMx->CNTCON_CLR = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum); + } + + if (countConfig->countRising == ENABLE) + { + MCPWMx->CNTCON_SET = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum); + } + else + { + MCPWMx->CNTCON_CLR = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum); + } + } + else + { + MCPWMx->CNTCON_CLR = MCPWM_CNTCON_CNTR(channelNum); + } + } +} + + +/*********************************************************************//** + * @brief Start MCPWM activity for each MCPWM channel + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] channel0 State of this command on channel 0: + * - ENABLE: 'Start' command will effect on channel 0 + * - DISABLE: 'Start' command will not effect on channel 0 + * @param[in] channel1 State of this command on channel 1: + * - ENABLE: 'Start' command will effect on channel 1 + * - DISABLE: 'Start' command will not effect on channel 1 + * @param[in] channel2 State of this command on channel 2: + * - ENABLE: 'Start' command will effect on channel 2 + * - DISABLE: 'Start' command will not effect on channel 2 + * @return None + **********************************************************************/ +void MCPWM_Start(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channel0, + uint32_t channel1, uint32_t channel2) +{ + uint32_t regVal = 0; + + regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \ + | (channel2 ? MCPWM_CON_RUN(2) : 0); + + MCPWMx->CON_SET = regVal; +} + + +/*********************************************************************//** + * @brief Stop MCPWM activity for each MCPWM channel + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] channel0 State of this command on channel 0: + * - ENABLE: 'Stop' command will effect on channel 0 + * - DISABLE: 'Stop' command will not effect on channel 0 + * @param[in] channel1 State of this command on channel 1: + * - ENABLE: 'Stop' command will effect on channel 1 + * - DISABLE: 'Stop' command will not effect on channel 1 + * @param[in] channel2 State of this command on channel 2: + * - ENABLE: 'Stop' command will effect on channel 2 + * - DISABLE: 'Stop' command will not effect on channel 2 + * @return None + **********************************************************************/ +void MCPWM_Stop(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channel0, + uint32_t channel1, uint32_t channel2) +{ + uint32_t regVal = 0; + + regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \ + | (channel2 ? MCPWM_CON_RUN(2) : 0); + + MCPWMx->CON_CLR = regVal; +} + + +/*********************************************************************//** + * @brief Enables/Disables 3-phase AC motor mode on MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] acMode State of this command, should be: + * - ENABLE. + * - DISABLE. + * @return None + **********************************************************************/ +void MCPWM_ACMode(LPC_MCPWM_TypeDef *MCPWMx, uint32_t acMode) +{ + if (acMode) + { + MCPWMx->CON_SET = MCPWM_CON_ACMODE; + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_ACMODE; + } +} + + +/*********************************************************************//** + * @brief Enables/Disables 3-phase DC motor mode on MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] dcMode State of this command, should be: + * - ENABLE. + * - DISABLE. + * @param[in] outputInvered Polarity of the MCOB outputs for all 3 channels, + * should be: + * - ENABLE: The MCOB outputs have opposite polarity + * from the MCOA outputs. + * - DISABLE: The MCOB outputs have the same basic + * polarity as the MCOA outputs. + * @param[in] outputPattern A value contains bits that enables/disables the specified + * output pins route to the internal MCOA0 signal, should be: + - MCPWM_PATENT_A0: MCOA0 tracks internal MCOA0 + - MCPWM_PATENT_B0: MCOB0 tracks internal MCOA0 + - MCPWM_PATENT_A1: MCOA1 tracks internal MCOA0 + - MCPWM_PATENT_B1: MCOB1 tracks internal MCOA0 + - MCPWM_PATENT_A2: MCOA2 tracks internal MCOA0 + - MCPWM_PATENT_B2: MCOB2 tracks internal MCOA0 + * @return None + * + * Note: all these outputPatent values above can be ORed together for using as input parameter. + **********************************************************************/ +void MCPWM_DCMode(LPC_MCPWM_TypeDef *MCPWMx, uint32_t dcMode, + uint32_t outputInvered, uint32_t outputPattern) +{ + if (dcMode) + { + MCPWMx->CON_SET = MCPWM_CON_DCMODE; + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_DCMODE; + } + + if (outputInvered) + { + MCPWMx->CON_SET = MCPWM_CON_INVBDC; + } + else + { + MCPWMx->CON_CLR = MCPWM_CON_INVBDC; + } + + MCPWMx->CP = outputPattern; +} + + +/*********************************************************************//** + * @brief Configures the specified interrupt in MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be: LPC_MCPWM + * @param[in] ulIntType Interrupt type, should be: + * - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0) + * - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0) + * - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0) + * - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1) + * - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1) + * - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1) + * - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2) + * - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2) + * - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2) + * - MCPWM_INTFLAG_ABORT: Fast abort interrupt + * @param[in] NewState New State of this command, should be: + * - ENABLE. + * - DISABLE. + * @return None + * + * Note: all these ulIntType values above can be ORed together for using as input parameter. + **********************************************************************/ +void MCPWM_IntConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType, FunctionalState NewState) +{ + if (NewState) + { + MCPWMx->INTEN_SET = ulIntType; + } + else + { + MCPWMx->INTEN_CLR = ulIntType; + } +} + + +/*********************************************************************//** + * @brief Sets/Forces the specified interrupt for MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected + * Should be LPC_MCPWM + * @param[in] ulIntType Interrupt type, should be: + * - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0) + * - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0) + * - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0) + * - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1) + * - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1) + * - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1) + * - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2) + * - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2) + * - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2) + * - MCPWM_INTFLAG_ABORT: Fast abort interrupt + * @return None + * Note: all these ulIntType values above can be ORed together for using as input parameter. + **********************************************************************/ +void MCPWM_IntSet(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType) +{ + MCPWMx->INTF_SET = ulIntType; +} + + +/*********************************************************************//** + * @brief Clear the specified interrupt pending for MCPWM peripheral + * @param[in] MCPWMx Motor Control PWM peripheral selected, + * should be: LPC_MCPWM + * @param[in] ulIntType Interrupt type, should be: + * - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0) + * - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0) + * - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0) + * - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1) + * - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1) + * - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1) + * - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2) + * - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2) + * - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2) + * - MCPWM_INTFLAG_ABORT: Fast abort interrupt + * @return None + * Note: all these ulIntType values above can be ORed together for using as input parameter. + **********************************************************************/ +void MCPWM_IntClear(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType) +{ + MCPWMx->INTF_CLR = ulIntType; +} + + +/*********************************************************************//** + * @brief Check whether if the specified interrupt in MCPWM is set or not + * @param[in] MCPWMx Motor Control PWM peripheral selected, + * should be: LPC_MCPWM + * @param[in] ulIntType Interrupt type, should be: + * - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0) + * - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0) + * - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0) + * - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1) + * - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1) + * - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1) + * - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2) + * - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2) + * - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2) + * - MCPWM_INTFLAG_ABORT: Fast abort interrupt + * @return None + **********************************************************************/ +FlagStatus MCPWM_GetIntStatus(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType) +{ + return ((MCPWMx->INTF & ulIntType) ? SET : RESET); +} + +/** + * @} + */ + +#endif /*_MCPWM*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_nvic.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_nvic.c new file mode 100644 index 0000000000000000000000000000000000000000..3de1316a8228596a6a100264934f844e9901cd19 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_nvic.c @@ -0,0 +1,156 @@ +/********************************************************************** +* $Id$ lpc_nvic.c 2011-06-02 +*//** +* @file lpc_nvic.c +* @brief Contains all expansion functions support for Nesting +* Vectored Interrupt Controller (NVIC) firmware library +* on LPC. The main NVIC functions are defined +* in core_cm3.h +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup NVIC + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _NVIC + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_nvic.h" + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup NVIC_Private_Macros NVIC Private Macros + * @{ + */ + +/* Vector table offset bit mask */ +#define NVIC_VTOR_MASK 0x3FFFFF80 + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup NVIC_Public_Functions + * @{ + */ + + +/*****************************************************************************//** + * @brief De-initializes the NVIC peripheral registers to their default + * reset values. + * @param None + * @return None + * + * These following NVIC peripheral registers will be de-initialized: + * - Disable Interrupt (32 IRQ interrupt sources that matched with LPC178X) + * - Clear all Pending Interrupts (32 IRQ interrupt source that matched with LPC178X) + * - Clear all Interrupt Priorities (32 IRQ interrupt source that matched with LPC178X) + *******************************************************************************/ +void NVIC_DeInit(void) +{ + uint8_t tmp; + + /* Disable all interrupts */ + NVIC->ICER[0] = 0xFFFFFFFF; + NVIC->ICER[1] = 0x00000001; + /* Clear all pending interrupts */ + NVIC->ICPR[0] = 0xFFFFFFFF; + NVIC->ICPR[1] = 0x00000001; + + /* Clear all interrupt priority */ + for (tmp = 0; tmp < 32; tmp++) { + NVIC->IP[tmp] = 0x00; + } +} + +/*****************************************************************************//** + * @brief De-initializes the SCB peripheral registers to their default + * reset values. + * @param none + * @return none + * + * These following SCB NVIC peripheral registers will be de-initialized: + * - Interrupt Control State register + * - Interrupt Vector Table Offset register + * - Application Interrupt/Reset Control register + * - System Control register + * - Configuration Control register + * - System Handlers Priority Registers + * - System Handler Control and State Register + * - Configurable Fault Status Register + * - Hard Fault Status Register + * - Debug Fault Status Register + *******************************************************************************/ +void NVIC_SCBDeInit(void) +{ + uint8_t tmp; + + SCB->ICSR = 0x0A000000; + SCB->VTOR = 0x00000000; + SCB->AIRCR = 0x05FA0000; + SCB->SCR = 0x00000000; + SCB->CCR = 0x00000000; + + for (tmp = 0; tmp < 32; tmp++) { + SCB->SHP[tmp] = 0x00; + } + + SCB->SHCSR = 0x00000000; + SCB->CFSR = 0xFFFFFFFF; + SCB->HFSR = 0xFFFFFFFF; + SCB->DFSR = 0xFFFFFFFF; +} + + +/*****************************************************************************//** + * @brief Set Vector Table Offset value + * @param offset Offset value + * @return None + *******************************************************************************/ +void NVIC_SetVTOR(uint32_t offset) +{ +// SCB->VTOR = (offset & NVIC_VTOR_MASK); + SCB->VTOR = offset; +} + +/** + * @} + */ + +#endif /*_NVIC*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_pinsel.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_pinsel.c new file mode 100644 index 0000000000000000000000000000000000000000..61809f5bd671b01ec5ce0966ac6946a3a908c59f --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_pinsel.c @@ -0,0 +1,540 @@ +/********************************************************************** +* $Id$ lpc_pinsel.c 2011-06-02 +*//** +* @file lpc_pinsel.c +* @brief Contains all functions support for Pin-connection block +* firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup PINSEL + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _PINSEL + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_pinsel.h" + +/* Private Functions ---------------------------------------------------------- */ + +/*********************************************************************//** + * @brief Get pointer to GPIO peripheral due to GPIO port + * @param[in] portnum Port Number value, should be in range from 0..3. + * @param[in] pinnum Pin number value, should be in range from 0..31 + * @return Pointer to GPIO peripheral + **********************************************************************/ +static uint32_t * PIN_GetPointer(uint8_t portnum, uint8_t pinnum) +{ + uint32_t *pPIN = NULL; + pPIN = (uint32_t *)(LPC_IOCON_BASE + ((portnum * 32 + pinnum)*sizeof(uint32_t))); + return pPIN; +} + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup PINSEL_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Get type of a pin. + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @return Port type: + * - PINSEL_PIN_TYPE_D + * - PINSEL_PIN_TYPE_A + * - PINSEL_PIN_TYPE_I + * - PINSEL_PIN_TYPE_W + * - PINSEL_PIN_TYPE_U + * - PINSEL_PIN_TYPE_UNKNOWN: Invalid pin + **********************************************************************/ +PinSel_PinType PINSEL_GetPinType(uint8_t portnum, uint8_t pinnum) +{ + PinSel_PinType Ret = PINSEL_PIN_TYPE_UNKNOWN; + switch(portnum) + { + case 0: + if((pinnum <=6)|| + ((pinnum >= 10)&&(pinnum <=11))|| + ((pinnum >= 14)&&(pinnum <=22))) + Ret = PINSEL_PIN_TYPE_D; + else if ((pinnum == 12)||(pinnum==13)|| + ((pinnum >= 23)&&(pinnum <=26))) + Ret = PINSEL_PIN_TYPE_A; + else if ((pinnum == 29) || (pinnum==30)|| (pinnum==31)) + Ret = PINSEL_PIN_TYPE_U; + else if ((pinnum == 27) || (pinnum==28)) + Ret = PINSEL_PIN_TYPE_I; + else if ((pinnum == 7) || (pinnum==8)|| (pinnum==9)) + Ret = PINSEL_PIN_TYPE_W; + break; + case 1: + if(pinnum <=29) + Ret = PINSEL_PIN_TYPE_D; + else if ((pinnum == 30) || (pinnum==31)) + Ret = PINSEL_PIN_TYPE_A; + break; + case 2: + case 3: + case 4: + Ret = PINSEL_PIN_TYPE_D; + break; + case 5: + if((pinnum <=1)|| + (pinnum == 4)) + Ret = PINSEL_PIN_TYPE_D; + else if ((pinnum == 2) || (pinnum==3)) + Ret = PINSEL_PIN_TYPE_I; + break; + default: + break; + } + + return Ret; +} + +/*********************************************************************//** + * @brief Setup the pin selection function + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] funcnum Function number, should be range: 0..7 + * - 0: Select GPIO (Default) + * - 1: Selects the 1st alternate function + * - 2: Selects the 2nd alternate function + * ... + * - 7: Selects the 7th alternate function + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_ConfigPin ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + + pPIN = PIN_GetPointer(portnum, pinnum); + *pPIN &= ~IOCON_FUNC_MASK;//Clear function bits + *pPIN |= funcnum&IOCON_FUNC_MASK; + + return PINSEL_RET_OK; +} + + +/*********************************************************************//** + * @brief Setup resistor mode for pin of type D,A,W + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] modenum: Mode number, should be in range: 0..3 + - PINSEL_BASICMODE_PLAINOUT: Plain output + - PINSEL_BASICMODE_PULLDOWN: Pull-down enable + - PINSEL_BASICMODE_PULLUP: Pull-up enable + - PINSEL_BASICMODE_REPEATER: Repeater mode + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetPinMode ( uint8_t portnum, uint8_t pinnum, PinSel_BasicMode modenum) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if((type != PINSEL_PIN_TYPE_D )&& + (type != PINSEL_PIN_TYPE_A )&& + (type != PINSEL_PIN_TYPE_W)) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + *(uint32_t *)pPIN &= ~(IOCON_MODE_MASK);//Clear function bits + *(uint32_t *)pPIN |= (modenum << IOCON_MODE_POS)&IOCON_MODE_MASK; + + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Setup hysteresis for pin of type D, W + * @param[in] portnum Port number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] NewState new state of Hysteresis mode, should be: + * - ENABLE: Hysteresis enable + * - DISABLE: Hysteresis disable + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetHysMode(uint8_t portnum, uint8_t pinnum, FunctionalState NewState) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if((type != PINSEL_PIN_TYPE_D )&& + (type != PINSEL_PIN_TYPE_W)) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + if(NewState == DISABLE) + { + *(uint32_t *)pPIN &= ~IOCON_HYS_ENABLE;//Clear hys bits + } + else + *(uint32_t *)pPIN |= IOCON_HYS_ENABLE; + + return PINSEL_RET_OK; +} +/*********************************************************************//** + * @brief Setup input polarity for pin of type A,I,D,W + * @param[in] portnum Port number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] NewState new state of Invert mode, should be: + * - ENABLE: Input is inverted. + * - DISABLE: Input isn't inverted. + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetInvertInput(uint8_t portnum, uint8_t pinnum, FunctionalState NewState) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if(type== PINSEL_PIN_TYPE_U) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + if(NewState == DISABLE) + { + *(uint32_t *)pPIN &= ~IOCON_INVERT_INPUT;//Clear hys bits + } + else + *(uint32_t *)pPIN |= IOCON_INVERT_INPUT; + + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Setup Slew rate for pin of type D,W + * @param[in] portnum Port number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] NewState new state of Slew rate control, should be: + * - ENABLE: Output slew rate control is enable + * - DISABLE: Output slew rate control is disable + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetSlewMode(uint8_t portnum, uint8_t pinnum, FunctionalState NewState) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if((type!= PINSEL_PIN_TYPE_D) && + (type!= PINSEL_PIN_TYPE_W)) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + if(NewState == DISABLE) + { + *(uint32_t *)pPIN &= ~IOCON_SLEW_ENABLE;//Clear hys bits + } + else + *(uint32_t *)pPIN |= IOCON_SLEW_ENABLE; + + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Setup I2CMode for only pins that provide special I2C functionality + * @param[in] portnum Port number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] I2CMode I2C mode, should be: + * - PINSEL_I2CMODE_FAST_STANDARD: Fast mode and standard I2C mode + * - PINSEL_I2CMODE_OPENDRAINIO: Open drain I/O + * - PINSEL_I2CMODE_FASTMODEPLUS: Fast Mode Plus I/O + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetI2CMode(uint8_t portnum, uint8_t pinnum, PinSel_I2cMode I2CMode) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if(type != PINSEL_PIN_TYPE_I ) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + + switch(I2CMode) + { + // Standard/Fast Mode I2C: HS = HIDRIVE = 0 + case PINSEL_I2CMODE_FAST_STANDARD: + PINSEL_SetI2CFilter(portnum,pinnum,ENABLE); + *(uint32_t *)pPIN &= ~(IOCON_I2CMODE_FASTPLUS); + break; + + // Non-I2C: HS = 1, HIDRIVE = 0 + case PINSEL_I2CMODE_OPENDRAINIO: + PINSEL_SetI2CFilter(portnum,pinnum,DISABLE); + *(uint32_t *)pPIN &= ~(IOCON_I2CMODE_FASTPLUS); + break; + + // Fast Mode Plus I2C: HS = 0, HIDRIVE =1 + case PINSEL_I2CMODE_FASTMODEPLUS: + PINSEL_SetI2CFilter(portnum,pinnum,ENABLE); + *(uint32_t *)pPIN |= (IOCON_I2CMODE_FASTPLUS); + break; + default: + return PINSEL_RET_ERR; + } + + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Setup Open-drain mode in pin of type D, A, W + * @param[in] portnum Port number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] NewState new state of Open-drain mode: + * - DISABLE: Normal pin I/O mode + * - ENABLE: Open-drain enable + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetOpenDrainMode(uint8_t portnum, uint8_t pinnum, FunctionalState NewState) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if((type != PINSEL_PIN_TYPE_D ) && + (type != PINSEL_PIN_TYPE_A ) && + (type != PINSEL_PIN_TYPE_W )) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + if(NewState == DISABLE) + { + *(uint32_t *)pPIN &= ~IOCON_OPENDRAIN_MODE;//Clear hys bits + } + else + { + *(uint32_t *)pPIN |= IOCON_OPENDRAIN_MODE; + } + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Enable the Analog mode for each pin of Type A(default is as Digital pins) + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] enable: the state of the pin that is expected to run + - ENABLE: Enable the DAC mode of the pin + - DISABLE: Disable the DAC mode + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetAnalogPinMode (uint8_t portnum, uint8_t pinnum, uint8_t enable) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if(type != PINSEL_PIN_TYPE_A ) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + + if(enable) + { + *(uint32_t *)pPIN &= ~(IOCON_DIGITIAL_MODE); + } + else + { + *(uint32_t *)pPIN |= IOCON_DIGITIAL_MODE;//Set 7th bit to one + } + + return PINSEL_RET_OK; +} + + + +/*********************************************************************//** + * @brief Choose the DAC mode for pin P0.26 + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] enable: the state of the pin that is expected to run + - ENABLE: Enable the DAC mode of the pin + - DISABLE: Disable the DAC mode + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_DacEnable (uint8_t portnum, uint8_t pinnum, uint8_t enable) +{ + uint32_t *pPIN = NULL; + + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + + // This setting is only for DAC pin (output pin) + if(!((portnum == 0) && (pinnum == 26))) + { + return PINSEL_RET_NOT_SUPPORT; + } + + pPIN = PIN_GetPointer(portnum, pinnum); + + if(enable) + { + *(uint32_t *)pPIN |= IOCON_DAC_ENABLE;//Set 16th bit to one + } + else + { + *(uint32_t *)pPIN &= ~IOCON_DAC_ENABLE;//Set 16th bit to one + + } + + return PINSEL_RET_OK; +} + +/*********************************************************************//** + * @brief Control the 10ns glitch filter for pin of type A,W + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] enable: the state of the pin that is expected to run + - ENABLE: The noise pulses below approximately 10ns are filtered out + - DISABLE: No input filtering is done. + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetFilter (uint8_t portnum, uint8_t pinnum, uint8_t enable) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if((type != PINSEL_PIN_TYPE_A ) && + (type != PINSEL_PIN_TYPE_W )) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + + + if(enable) + { + *(uint32_t *)pPIN &= ~(IOCON_10ns_FILTER_DISABLE);//Clear 8th bit to 0 + } + else + { + *(uint32_t *)pPIN |= (IOCON_10ns_FILTER_DISABLE);//Set 8th bit to one + } + + + return PINSEL_RET_OK; +} +/*********************************************************************//** + * @brief Control the 50ns glitch filter for I2C pins (type I) + * @param[in] portnum PORT number, should be in range: 0..3 + * @param[in] pinnum Pin number, should be in range: 0..31 + * @param[in] enable: the state of the pin that is expected to run + - ENABLE: The noise pulses below approximately 10ns are filtered out + - DISABLE: No input filtering is done. + * @return PINSEL Return Code + * - PINSEL_RET_INVALID_PIN + * - PINSEL_RET_NOT_SUPPORT + * - PINSEL_RET_OK + **********************************************************************/ +PINSEL_RET_CODE PINSEL_SetI2CFilter (uint8_t portnum, uint8_t pinnum, uint8_t enable) +{ + uint32_t *pPIN = NULL; + PinSel_PinType type = PINSEL_GetPinType(portnum,pinnum); + + if(type == PINSEL_PIN_TYPE_UNKNOWN) + return PINSEL_RET_INVALID_PIN; + if(type != PINSEL_PIN_TYPE_I) + return PINSEL_RET_NOT_SUPPORT; + + pPIN = PIN_GetPointer(portnum, pinnum); + + + if(enable) + { + *(uint32_t *)pPIN &= ~(IOCON_HS_MASK);//Clear 8th bit to 0 + } + else + { + *(uint32_t *)pPIN |= (IOCON_I2C_FILTER_DISABLE);//Set 8th bit to one + } + + + return PINSEL_RET_OK; +} + + +/** + * @} + */ +#endif /*_PINSEL*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_pwm.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..a9c79c25c4dafc45d6079679dafc9cd0ccaa5ca8 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_pwm.c @@ -0,0 +1,579 @@ +/********************************************************************** +* $Id$ lpc_pwm.c 2011-06-02 +*//** +* @file lpc_pwm.c +* @brief Contains all functions support for PWM firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup PWM + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _PWM + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_pwm.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup PWM_Public_Functions + * @{ + */ + +static LPC_PWM_TypeDef* PWM_GetPointer (uint8_t pwmId); + +/*********************************************************************//** + * @brief Setting CAN baud rate (bps) + * @param[in] canId point to LPC_CAN_TypeDef object, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @return The pointer to CAN peripheral that's expected to use + ***********************************************************************/ +static LPC_PWM_TypeDef* PWM_GetPointer (uint8_t pwmId) +{ + LPC_PWM_TypeDef* pPwm; + + switch (pwmId) + { + case PWM_0: + pPwm = LPC_PWM0; + break; + + case PWM_1: + pPwm = LPC_PWM1; + break; + + default: + pPwm = NULL; + break; + } + + return pPwm; +} + + +/*********************************************************************//** + * @brief Check whether specified interrupt flag in PWM is set or not + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] IntFlag: PWM interrupt flag, should be: + * - PWM_INTSTAT_MR0: Interrupt flag for PWM match channel 0 + * - PWM_INTSTAT_MR1: Interrupt flag for PWM match channel 1 + * - PWM_INTSTAT_MR2: Interrupt flag for PWM match channel 2 + * - PWM_INTSTAT_MR3: Interrupt flag for PWM match channel 3 + * - PWM_INTSTAT_MR4: Interrupt flag for PWM match channel 4 + * - PWM_INTSTAT_MR5: Interrupt flag for PWM match channel 5 + * - PWM_INTSTAT_MR6: Interrupt flag for PWM match channel 6 + * - PWM_INTSTAT_CAP0: Interrupt flag for capture input 0 + * - PWM_INTSTAT_CAP1: Interrupt flag for capture input 1 + * @return New State of PWM interrupt flag (SET or RESET) + **********************************************************************/ +IntStatus PWM_GetIntStatus(uint8_t pwmId, uint32_t IntFlag) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + return ((pPwm->IR & IntFlag) ? SET : RESET); +} + + + +/*********************************************************************//** + * @brief Clear specified PWM Interrupt pending + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] IntFlag: PWM interrupt flag, should be: + * - PWM_INTSTAT_MR0: Interrupt flag for PWM match channel 0 + * - PWM_INTSTAT_MR1: Interrupt flag for PWM match channel 1 + * - PWM_INTSTAT_MR2: Interrupt flag for PWM match channel 2 + * - PWM_INTSTAT_MR3: Interrupt flag for PWM match channel 3 + * - PWM_INTSTAT_MR4: Interrupt flag for PWM match channel 4 + * - PWM_INTSTAT_MR5: Interrupt flag for PWM match channel 5 + * - PWM_INTSTAT_MR6: Interrupt flag for PWM match channel 6 + * - PWM_INTSTAT_CAP0: Interrupt flag for capture input 0 + * - PWM_INTSTAT_CAP1: Interrupt flag for capture input 1 + * @return None + **********************************************************************/ +void PWM_ClearIntPending(uint8_t pwmId, uint32_t IntFlag) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + pPwm->IR = IntFlag; +} + + + +/*****************************************************************************//** +* @brief Fills each PWM_InitStruct member with its default value: +* - If PWMCounterMode = PWM_MODE_TIMER: +* + PrescaleOption = PWM_TIMER_PRESCALE_USVAL +* + PrescaleValue = 1 +* - If PWMCounterMode = PWM_MODE_COUNTER: +* + CountInputSelect = PWM_COUNTER_PCAP1_0 +* + CounterOption = PWM_COUNTER_RISING +* @param[in] PWMTimerCounterMode Timer or Counter mode, should be: +* - PWM_MODE_TIMER: Counter of PWM peripheral is in Timer mode +* - PWM_MODE_COUNTER: Counter of PWM peripheral is in Counter mode +* @param[in] PWM_InitStruct Pointer to structure (PWM_TIMERCFG_Type or +* PWM_COUNTERCFG_Type) which will be initialized. +* @return None +* Note: PWM_InitStruct pointer will be assigned to corresponding structure +* (PWM_TIMERCFG_Type or PWM_COUNTERCFG_Type) due to PWMTimerCounterMode. +*******************************************************************************/ +void PWM_ConfigStructInit(uint8_t PWMTimerCounterMode, void *PWM_InitStruct) +{ + PWM_TIMERCFG_Type *pTimeCfg; + PWM_COUNTERCFG_Type *pCounterCfg; + + pTimeCfg = (PWM_TIMERCFG_Type *) PWM_InitStruct; + pCounterCfg = (PWM_COUNTERCFG_Type *) PWM_InitStruct; + + if (PWMTimerCounterMode == PWM_MODE_TIMER ) + { + pTimeCfg->PrescaleOption = PWM_TIMER_PRESCALE_USVAL; + pTimeCfg->PrescaleValue = 1; + } + else if (PWMTimerCounterMode == PWM_MODE_COUNTER) + { + pCounterCfg->CountInputSelect = PWM_COUNTER_PCAP1_0; + pCounterCfg->CounterOption = PWM_COUNTER_RISING; + } +} + + +/*********************************************************************//** + * @brief Initializes the pPwm peripheral corresponding to the specified + * parameters in the PWM_ConfigStruct. + * @param[in] pwmId The Id of the expected PWM component + * + * + * @param[in] PWMTimerCounterMode Timer or Counter mode, should be: + * - PWM_MODE_TIMER: Counter of PWM peripheral is in Timer mode + * - PWM_MODE_COUNTER: Counter of PWM peripheral is in Counter mode + * @param[in] PWM_ConfigStruct Pointer to structure (PWM_TIMERCFG_Type or + * PWM_COUNTERCFG_Type) which will be initialized. + * @return None + * Note: PWM_ConfigStruct pointer will be assigned to corresponding structure + * (PWM_TIMERCFG_Type or PWM_COUNTERCFG_Type) due to PWMTimerCounterMode. + **********************************************************************/ +void PWM_Init(uint8_t pwmId, uint32_t PWMTimerCounterMode, void *PWM_ConfigStruct) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + PWM_TIMERCFG_Type *pTimeCfg; + PWM_COUNTERCFG_Type *pCounterCfg; + uint64_t clkdlycnt; + + pTimeCfg = (PWM_TIMERCFG_Type *)PWM_ConfigStruct; + pCounterCfg = (PWM_COUNTERCFG_Type *)PWM_ConfigStruct; + + if(pwmId == PWM_0) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM0, ENABLE); + } + else if(pwmId == PWM_1) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM1, ENABLE); + } + else + { + //Trap the error + while(1); + } + + // Get peripheral clock of PWM1 + clkdlycnt = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + // Clear all interrupts pending + pPwm->IR = 0xFF & PWM_IR_BITMASK; + pPwm->TCR = 0x00; + pPwm->CTCR = 0x00; + pPwm->MCR = 0x00; + pPwm->CCR = 0x00; + pPwm->PCR = 0x00; + pPwm->LER = 0x00; + + if (PWMTimerCounterMode == PWM_MODE_TIMER) + { + /* Absolute prescale value */ + if (pTimeCfg->PrescaleOption == PWM_TIMER_PRESCALE_TICKVAL) + { + pPwm->PR = pTimeCfg->PrescaleValue - 1; + } + /* uSecond prescale value */ + else + { + clkdlycnt = (clkdlycnt * pTimeCfg->PrescaleValue) / 1000000; + pPwm->PR = ((uint32_t) clkdlycnt) - 1; + } + + } + else if (PWMTimerCounterMode == PWM_MODE_COUNTER) + { + + pPwm->CTCR |= (PWM_CTCR_MODE((uint32_t)pCounterCfg->CounterOption)) \ + | (PWM_CTCR_SELECT_INPUT((uint32_t)pCounterCfg->CountInputSelect)); + } +} + +/*********************************************************************//** + * @brief De-initializes the PWM peripheral registers to their +* default reset values. + * @param[in] pwmId The Id of the expected PWM component + * + * @return None + **********************************************************************/ +void PWM_DeInit (uint8_t pwmId) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + // Disable PWM control (timer, counter and PWM) + pPwm->TCR = 0x00; + + if(pwmId == PWM_0) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM0, DISABLE); + } + else if(pwmId == PWM_1) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM1, DISABLE); + } +} + + +/*********************************************************************//** + * @brief Enable/Disable PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable PWM peripheral + * - DISABLE: Disable PWM peripheral + * @return None + **********************************************************************/ +void PWM_Cmd(uint8_t pwmId, FunctionalState NewState) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + if (NewState == ENABLE) + { + pPwm->TCR |= PWM_TCR_PWM_ENABLE; + } + else + { + pPwm->TCR &= (~PWM_TCR_PWM_ENABLE) & PWM_TCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Enable/Disable Counter in PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable Counter in PWM peripheral + * - DISABLE: Disable Counter in PWM peripheral + * @return None + **********************************************************************/ +void PWM_CounterCmd(uint8_t pwmId, FunctionalState NewState) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + if (NewState == ENABLE) + { + pPwm->TCR |= PWM_TCR_COUNTER_ENABLE; + } + else + { + pPwm->TCR &= (~PWM_TCR_COUNTER_ENABLE) & PWM_TCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Reset Counter in PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @return None + **********************************************************************/ +void PWM_ResetCounter(uint8_t pwmId) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + pPwm->TCR |= PWM_TCR_COUNTER_RESET; + + pPwm->TCR &= (~PWM_TCR_COUNTER_RESET) & PWM_TCR_BITMASK; +} + + +/*********************************************************************//** + * @brief Configures match for PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] PWM_MatchConfigStruct Pointer to a PWM_MATCHCFG_Type structure +* that contains the configuration information for the +* specified PWM match function. + * @return None + **********************************************************************/ +void PWM_ConfigMatch(uint8_t pwmId, PWM_MATCHCFG_Type *PWM_MatchConfigStruct) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + //interrupt on MRn + if (PWM_MatchConfigStruct->IntOnMatch == ENABLE) + { + pPwm->MCR |= PWM_MCR_INT_ON_MATCH(PWM_MatchConfigStruct->MatchChannel); + } + else + { + pPwm->MCR &= (~ PWM_MCR_INT_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \ + & PWM_MCR_BITMASK; + } + + //reset on MRn + if (PWM_MatchConfigStruct->ResetOnMatch == ENABLE) + { + pPwm->MCR |= PWM_MCR_RESET_ON_MATCH(PWM_MatchConfigStruct->MatchChannel); + } + else + { + pPwm->MCR &= (~ PWM_MCR_RESET_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \ + & PWM_MCR_BITMASK; + } + + //stop on MRn + if (PWM_MatchConfigStruct->StopOnMatch == ENABLE) + { + pPwm->MCR |= PWM_MCR_STOP_ON_MATCH(PWM_MatchConfigStruct->MatchChannel); + } + else + { + pPwm->MCR &= (~ PWM_MCR_STOP_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \ + & PWM_MCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Configures capture input for PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] PWM_CaptureConfigStruct Pointer to a PWM_CAPTURECFG_Type structure + * that contains the configuration information for the + * specified PWM capture input function. + * @return None + **********************************************************************/ +void PWM_ConfigCapture(uint8_t pwmId, PWM_CAPTURECFG_Type *PWM_CaptureConfigStruct) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + if (PWM_CaptureConfigStruct->RisingEdge == ENABLE) + { + pPwm->CCR |= PWM_CCR_CAP_RISING(PWM_CaptureConfigStruct->CaptureChannel); + } + else + { + pPwm->CCR &= (~ PWM_CCR_CAP_RISING(PWM_CaptureConfigStruct->CaptureChannel)) \ + & PWM_CCR_BITMASK; + } + + if (PWM_CaptureConfigStruct->FallingEdge == ENABLE) + { + pPwm->CCR |= PWM_CCR_CAP_FALLING(PWM_CaptureConfigStruct->CaptureChannel); + } + else + { + pPwm->CCR &= (~ PWM_CCR_CAP_FALLING(PWM_CaptureConfigStruct->CaptureChannel)) \ + & PWM_CCR_BITMASK; + } + + if (PWM_CaptureConfigStruct->IntOnCaption == ENABLE) + { + pPwm->CCR |= PWM_CCR_INT_ON_CAP(PWM_CaptureConfigStruct->CaptureChannel); + } + else + { + pPwm->CCR &= (~ PWM_CCR_INT_ON_CAP(PWM_CaptureConfigStruct->CaptureChannel)) \ + & PWM_CCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Read value of capture register PWM peripheral + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] CaptureChannel: capture channel number, should be in + * range 0 to 1 + * @return Value of capture register + **********************************************************************/ +uint32_t PWM_GetCaptureValue(uint8_t pwmId, uint8_t CaptureChannel) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + switch (CaptureChannel) + { + case 0: + return pPwm->CR0; + + case 1: + return pPwm->CR1; + + default: + return (0); + } +} + + +/********************************************************************//** + * @brief Update value for each PWM channel with update type option + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] MatchChannel Match channel + * @param[in] MatchValue Match value + * @param[in] UpdateType Type of Update, should be: + * - PWM_MATCH_UPDATE_NOW: The update value will be updated for + * this channel immediately + * - PWM_MATCH_UPDATE_NEXT_RST: The update value will be updated for + * this channel on next reset by a PWM Match event. + * @return None + *********************************************************************/ +void PWM_MatchUpdate(uint8_t pwmId, uint8_t MatchChannel, + uint32_t MatchValue, uint8_t UpdateType) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + switch (MatchChannel) + { + case 0: + pPwm->MR0 = MatchValue; + break; + + case 1: + pPwm->MR1 = MatchValue; + break; + + case 2: + pPwm->MR2 = MatchValue; + break; + + case 3: + pPwm->MR3 = MatchValue; + break; + + case 4: + pPwm->MR4 = MatchValue; + break; + + case 5: + pPwm->MR5 = MatchValue; + break; + + case 6: + pPwm->MR6 = MatchValue; + break; + } + + // Write Latch register + pPwm->LER |= PWM_LER_EN_MATCHn_LATCH(MatchChannel); + + // In case of update now + if (UpdateType == PWM_MATCH_UPDATE_NOW) + { + pPwm->TCR |= PWM_TCR_COUNTER_RESET; + pPwm->TCR &= (~PWM_TCR_COUNTER_RESET) & PWM_TCR_BITMASK; + } +} + + +/********************************************************************//** + * @brief Configure Edge mode for each PWM channel + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] PWMChannel PWM channel, should be in range from 2 to 6 + * @param[in] ModeOption PWM mode option, should be: + * - PWM_CHANNEL_SINGLE_EDGE: Single Edge mode + * - PWM_CHANNEL_DUAL_EDGE: Dual Edge mode + * @return None + * Note: PWM Channel 1 can not be selected for mode option + *********************************************************************/ +void PWM_ChannelConfig(uint8_t pwmId, uint8_t PWMChannel, uint8_t ModeOption) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + // Single edge mode + if (ModeOption == PWM_CHANNEL_SINGLE_EDGE) + { + pPwm->PCR &= (~ PWM_PCR_PWMSELn(PWMChannel)) & PWM_PCR_BITMASK; + } + // Double edge mode + else if (PWM_CHANNEL_DUAL_EDGE) + { + pPwm->PCR |= PWM_PCR_PWMSELn(PWMChannel); + } +} + + + +/********************************************************************//** + * @brief Enable/Disable PWM channel output + * @param[in] pwmId The Id of the expected PWM component + * + * @param[in] PWMChannel PWM channel, should be in range from 1 to 6 + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable this PWM channel output + * - DISABLE: Disable this PWM channel output + * @return None + *********************************************************************/ +void PWM_ChannelCmd(uint8_t pwmId, uint8_t PWMChannel, FunctionalState NewState) +{ + LPC_PWM_TypeDef* pPwm = PWM_GetPointer(pwmId); + + if (NewState == ENABLE) + { + pPwm->PCR |= PWM_PCR_PWMENAn(PWMChannel); + } + else + { + pPwm->PCR &= (~ PWM_PCR_PWMENAn(PWMChannel)) & PWM_PCR_BITMASK; + } +} + +/** + * @} + */ + +#endif /*_PWM*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_qei.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_qei.c new file mode 100644 index 0000000000000000000000000000000000000000..8c098a7b69362b2878d30d61708290738d93ca0b --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_qei.c @@ -0,0 +1,599 @@ +/********************************************************************** +* $Id$ lpc_qei.c 2011-06-02 +*//** +* @file lpc_qei.c +* @brief Contains all functions support for QEI firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup QEI + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _QEI + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_qei.h" +#include "lpc_clkpwr.h" + +/* Private Types -------------------------------------------------------------- */ +/** @defgroup QEI_Private_Types QEI Private Types + * @{ + */ + +/** + * @brief QEI configuration union type definition + */ +typedef union { + QEI_CFG_Type bmQEIConfig; + uint32_t ulQEIConfig; +} QEI_CFGOPT_Type; + +/** + * @} + */ + +LPC_QEI_TypeDef* QEI_GetPointer(uint8_t qeiId); + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup QEI_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Get the point to typedef of QEI component + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * @return None + **********************************************************************/ +LPC_QEI_TypeDef* QEI_GetPointer(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = NULL; + + if(qeiId == 0) + { + pQei = LPC_QEI; + } + + return pQei; +} + + +/*********************************************************************//** + * @brief Resets value for each type of QEI value, such as velocity, + * counter, position, etc.. + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulResetType QEI Reset Type, should be one of the following: + * - QEI_RESET_POS: Reset Position Counter + * - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal + * - QEI_RESET_VEL: Reset Velocity + * - QEI_RESET_IDX: Reset Index Counter + * @return None + **********************************************************************/ +void QEI_Reset(uint8_t qeiId, uint32_t ulResetType) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->CON = ulResetType; +} + +/*********************************************************************//** + * @brief Initializes the QEI peripheral according to the specified +* parameters in the QEI_ConfigStruct. +* @param[in] qeiId The Id of the expected QEI component +* It should be 0 (zero) always with LPC +* +* @param[in] QEI_ConfigStruct Pointer to a QEI_CFG_Type structure +* that contains the configuration information for the +* specified QEI peripheral + * @return None + **********************************************************************/ +void QEI_Init(uint8_t qeiId, QEI_CFG_Type *QEI_ConfigStruct) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + /* Set up clock and power for QEI module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, ENABLE); + + // Reset all remaining value in QEI peripheral + + pQei->MAXPOS = 0x00; + pQei->CMPOS0 = 0x00; + pQei->CMPOS1 = 0x00; + pQei->CMPOS2 = 0x00; + pQei->INXCMP0 = 0x00; + pQei->VELCOMP = 0x00; + + pQei->LOAD = 0x00; + pQei->CON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI; + + pQei->FILTERPHA = 0x00; + pQei->FILTERPHB = 0x00; + pQei->FILTERINX = 0x00; + + // Disable all Interrupt + pQei->IEC = QEI_IECLR_BITMASK; + + // Clear all Interrupt pending + pQei->CLR = QEI_INTCLR_BITMASK; + + // Set QEI configuration value corresponding to its setting up value + pQei->CONF = ((QEI_CFGOPT_Type *)QEI_ConfigStruct)->ulQEIConfig; +} + + +/*********************************************************************//** + * @brief De-initializes the QEI peripheral registers to their + * default reset values. + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return None + **********************************************************************/ +void QEI_DeInit(uint8_t qeiId) +{ + /* Turn off clock and power for QEI module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, DISABLE); +} + + +/*****************************************************************************//** +* @brief Fills each QIE_InitStruct member with its default value: +* - DirectionInvert = QEI_DIRINV_NONE +* - SignalMode = QEI_SIGNALMODE_QUAD +* - CaptureMode = QEI_CAPMODE_4X +* - InvertIndex = QEI_INVINX_NONE +* @param[in] QIE_InitStruct Pointer to a QEI_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void QEI_GetCfgDefault(QEI_CFG_Type *QIE_InitStruct) +{ + QIE_InitStruct->CaptureMode = QEI_CAPMODE_4X; + QIE_InitStruct->DirectionInvert = QEI_DIRINV_NONE; + QIE_InitStruct->InvertIndex = QEI_INVINX_NONE; + QIE_InitStruct->SignalMode = QEI_SIGNALMODE_QUAD; +} + + +/*********************************************************************//** + * @brief Check whether if specified flag status is set or not + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulFlagType Status Flag Type, should be one of the following: + * - QEI_STATUS_DIR: Direction Status + * @return New Status of this status flag (SET or RESET) + **********************************************************************/ +FlagStatus QEI_GetStatus(uint8_t qeiId, uint32_t ulFlagType) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return ((pQei->STAT & ulFlagType) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Get current position value in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return Current position value of QEI peripheral + **********************************************************************/ +uint32_t QEI_GetPosition(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return (pQei->POS); +} + +/*********************************************************************//** + * @brief Set max position value for QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulMaxPos Max position value to set + * @return None + **********************************************************************/ +void QEI_SetMaxPosition(uint8_t qeiId, uint32_t ulMaxPos) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->MAXPOS = ulMaxPos; +} + +/*********************************************************************//** + * @brief Set position compare value for QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] bPosCompCh Compare Position channel, should be: + * - QEI_COMPPOS_CH_0: QEI compare position channel 0 + * - QEI_COMPPOS_CH_1: QEI compare position channel 1 + * - QEI_COMPPOS_CH_2: QEI compare position channel 2 + * @param[in] ulPosComp Compare Position value to set + * @return None + **********************************************************************/ +void QEI_SetPositionComp(uint8_t qeiId, uint8_t bPosCompCh, uint32_t ulPosComp) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + uint32_t *tmp; + + tmp = (uint32_t *) (&(pQei->CMPOS0) + bPosCompCh * 4); + *tmp = ulPosComp; +} + +/*********************************************************************//** + * @brief Get current index counter of QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return Current value of QEI index counter + **********************************************************************/ +uint32_t QEI_GetIndex(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return (pQei->INXCNT); +} + +/*********************************************************************//** + * @brief Set value for index compare in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulIndexComp Compare Index Value to set + * @return None + **********************************************************************/ +void QEI_SetIndexComp(uint8_t qeiId, uint32_t ulIndexComp) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->INXCMP0 = ulIndexComp; +} + +/*********************************************************************//** + * @brief Set timer reload value for QEI peripheral. When the velocity timer is + * over-flow, the value that set for Timer Reload register will be loaded + * into the velocity timer for next period. The calculated velocity in RPM + * therefore will be affect by this value. + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] QEIReloadStruct QEI reload structure + * @return None + **********************************************************************/ +void QEI_SetTimerReload(uint8_t qeiId, QEI_RELOADCFG_Type *QEIReloadStruct) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + uint64_t pclk; + + + if (QEIReloadStruct->ReloadOption == QEI_TIMERRELOAD_TICKVAL) + { + pQei->LOAD = QEIReloadStruct->ReloadValue - 1; + } + else + { +#if 1 + pclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + pclk = (pclk /(1000000/QEIReloadStruct->ReloadValue)) - 1; + + pQei->LOAD = (uint32_t)pclk; +#else + ld = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + if (ld/1000000 > 0) + { + ld /= 1000000; + ld *= QEIReloadStruct->ReloadValue; + ld -= 1; + } + else + { + ld *= QEIReloadStruct->ReloadValue; + ld /= 1000000; + ld -= 1; + } + + pQei->LOAD = ld; +#endif + } +} + +/*********************************************************************//** + * @brief Get current timer counter in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return Current timer counter in QEI peripheral + **********************************************************************/ +uint32_t QEI_GetTimer(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return (pQei->TIME); +} + +/*********************************************************************//** + * @brief Get current velocity pulse counter in current time period + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return Current velocity pulse counter value + **********************************************************************/ +uint32_t QEI_GetVelocity(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return (pQei->VEL); +} + +/*********************************************************************//** + * @brief Get the most recently measured velocity of the QEI. When + * the Velocity timer in QEI is over-flow, the current velocity + * value will be loaded into Velocity Capture register. + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @return The most recently measured velocity value + **********************************************************************/ +uint32_t QEI_GetVelocityCap(uint8_t qeiId) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return (pQei->CAP); +} + +/*********************************************************************//** + * @brief Set Velocity Compare value for QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulVelComp Compare Velocity value to set + * @return None + **********************************************************************/ +void QEI_SetVelocityComp(uint8_t qeiId, uint32_t ulVelComp) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->VELCOMP = ulVelComp; +} + +/*********************************************************************//** + * @brief Set value of sampling count for the digital filter in + * QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulSamplingPulse Value of sampling count to set + * @return None + **********************************************************************/ +void QEI_SetDigiFilter(uint8_t qeiId, st_Qei_FilterCfg FilterVal) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->FILTERPHA = FilterVal.PHA_FilterVal; + pQei->FILTERPHB = FilterVal.PHB_FilterVal; + pQei->FILTERINX = FilterVal.INX_FilterVal; +} + +/*********************************************************************//** + * @brief Check whether if specified interrupt flag status in QEI + * peripheral is set or not + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return New State of specified interrupt flag status (SET or RESET) + **********************************************************************/ +FlagStatus QEI_GetIntStatus(uint8_t qeiId, uint32_t ulIntType) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + return((pQei->INTSTAT & ulIntType) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Enable/Disable specified interrupt in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @param[in] NewState New function state, should be: + * - DISABLE + * - ENABLE + * @return None + **********************************************************************/ +void QEI_IntCmd(uint8_t qeiId, uint32_t ulIntType, FunctionalState NewState) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + if (NewState == ENABLE) + { + pQei->IES = ulIntType; + } + else + { + pQei->IEC = ulIntType; + } +} + + +/*********************************************************************//** + * @brief Sets (forces) specified interrupt in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + **********************************************************************/ +void QEI_IntSet(uint8_t qeiId, uint32_t ulIntType) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->SET = ulIntType; +} + +/*********************************************************************//** + * @brief Clear (force) specified interrupt (pending) in QEI peripheral + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + **********************************************************************/ +void QEI_IntClear(uint8_t qeiId, uint32_t ulIntType) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + pQei->CLR = ulIntType; +} + + +/*********************************************************************//** + * @brief Calculates the actual velocity in RPM passed via velocity + * capture value and Pulse Per Round (of the encoder) value + * parameter input. + * @param[in] qeiId The Id of the expected QEI component + * It should be 0 (zero) always with LPC + * + * @param[in] ulVelCapValue Velocity capture input value that can + * be got from QEI_GetVelocityCap() function + * @param[in] ulPPR Pulse per round of encoder + * @return The actual value of velocity in RPM (Round per minute) + **********************************************************************/ +uint32_t QEI_CalculateRPM(uint8_t qeiId, uint32_t ulVelCapValue, uint32_t ulPPR) +{ + LPC_QEI_TypeDef* pQei = QEI_GetPointer(qeiId); + + uint64_t rpm, clock, Load, edges; + + // Get current Clock rate for timer input + clock = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + // Get Timer load value (velocity capture period) + Load = (uint64_t)(pQei->LOAD + 1); + + // Get Edge + edges = (uint64_t)((pQei->CONF & QEI_CONF_CAPMODE) ? 4 : 2); + + // Calculate RPM + rpm = ((clock * ulVelCapValue * 60) / (Load * ulPPR * edges)); + + return (uint32_t)(rpm); +} + + +/** + * @} + */ + +#endif /*_QEI*/ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_rtc.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..9dd34b72285109425cd1789cde22f3e1273315dd --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_rtc.c @@ -0,0 +1,998 @@ +/********************************************************************** +* $Id$ lpc_rtc.c 2011-06-02 +*//** +* @file lpc_rtc.c +* @brief Contains all functions support for RTC firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup RTC + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _RTC + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_rtc.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup RTC_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initializes the RTC peripheral. + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @return None + *********************************************************************/ +void RTC_Init (LPC_RTC_TypeDef *RTCx) +{ + /* Set up clock and power for RTC module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, ENABLE); + + // Clear all register to be default + RTCx->ILR = 0x00; + RTCx->CCR = 0x00; + RTCx->CIIR = 0x00; + RTCx->AMR = 0xFF; + RTCx->CALIBRATION = 0x00; +} + + +/*********************************************************************//** + * @brief De-initializes the RTC peripheral registers to their +* default reset values. + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @return None + **********************************************************************/ +void RTC_DeInit(LPC_RTC_TypeDef *RTCx) +{ + RTCx->CCR = 0x00; + // Disable power and clock for RTC module + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, DISABLE); +} + +/*********************************************************************//** + * @brief Reset clock tick counter in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @return None + **********************************************************************/ +void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx) +{ + RTCx->CCR |= RTC_CCR_CTCRST; + RTCx->CCR &= (~RTC_CCR_CTCRST) & RTC_CCR_BITMASK; +} + +/*********************************************************************//** + * @brief Start/Stop RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] NewState New State of this function, should be: + * - ENABLE: The time counters are enabled + * - DISABLE: The time counters are disabled + * @return None + **********************************************************************/ +void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + RTCx->CCR |= RTC_CCR_CLKEN; + } + else + { + RTCx->CCR &= (~RTC_CCR_CLKEN) & RTC_CCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Enable/Disable Counter increment interrupt for each time type + * in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] CntIncrIntType: Counter Increment Interrupt type, + * an increment of this type value below will generates + * an interrupt, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @param[in] NewState New State of this function, should be: + * - ENABLE: Counter Increment interrupt for this + * time type are enabled + * - DISABLE: Counter Increment interrupt for this + * time type are disabled + * @return None + **********************************************************************/ +void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \ + FunctionalState NewState) +{ + if (NewState == ENABLE) + { + switch (CntIncrIntType) + { + case RTC_TIMETYPE_SECOND: + RTCx->CIIR |= RTC_CIIR_IMSEC; + break; + case RTC_TIMETYPE_MINUTE: + RTCx->CIIR |= RTC_CIIR_IMMIN; + break; + case RTC_TIMETYPE_HOUR: + RTCx->CIIR |= RTC_CIIR_IMHOUR; + break; + case RTC_TIMETYPE_DAYOFWEEK: + RTCx->CIIR |= RTC_CIIR_IMDOW; + break; + case RTC_TIMETYPE_DAYOFMONTH: + RTCx->CIIR |= RTC_CIIR_IMDOM; + break; + case RTC_TIMETYPE_DAYOFYEAR: + RTCx->CIIR |= RTC_CIIR_IMDOY; + break; + case RTC_TIMETYPE_MONTH: + RTCx->CIIR |= RTC_CIIR_IMMON; + break; + case RTC_TIMETYPE_YEAR: + RTCx->CIIR |= RTC_CIIR_IMYEAR; + break; + } + } + else + { + switch (CntIncrIntType) + { + case RTC_TIMETYPE_SECOND: + RTCx->CIIR &= (~RTC_CIIR_IMSEC) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_MINUTE: + RTCx->CIIR &= (~RTC_CIIR_IMMIN) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_HOUR: + RTCx->CIIR &= (~RTC_CIIR_IMHOUR) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFWEEK: + RTCx->CIIR &= (~RTC_CIIR_IMDOW) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFMONTH: + RTCx->CIIR &= (~RTC_CIIR_IMDOM) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFYEAR: + RTCx->CIIR &= (~RTC_CIIR_IMDOY) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_MONTH: + RTCx->CIIR &= (~RTC_CIIR_IMMON) & RTC_CIIR_BITMASK; + break; + case RTC_TIMETYPE_YEAR: + RTCx->CIIR &= (~RTC_CIIR_IMYEAR) & RTC_CIIR_BITMASK; + break; + } + } +} + + +/*********************************************************************//** + * @brief Enable/Disable Alarm interrupt for each time type + * in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] AlarmTimeType: Alarm Time Interrupt type, + * an matching of this type value below with current time + * in RTC will generates an interrupt, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @param[in] NewState New State of this function, should be: + * - ENABLE: Alarm interrupt for this + * time type are enabled + * - DISABLE: Alarm interrupt for this + * time type are disabled + * @return None + **********************************************************************/ +void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \ + FunctionalState NewState) +{ + if (NewState == ENABLE) + { + switch (AlarmTimeType) + { + case RTC_TIMETYPE_SECOND: + RTCx->AMR &= (~RTC_AMR_AMRSEC) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_MINUTE: + RTCx->AMR &= (~RTC_AMR_AMRMIN) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_HOUR: + RTCx->AMR &= (~RTC_AMR_AMRHOUR) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFWEEK: + RTCx->AMR &= (~RTC_AMR_AMRDOW) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFMONTH: + RTCx->AMR &= (~RTC_AMR_AMRDOM) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_DAYOFYEAR: + RTCx->AMR &= (~RTC_AMR_AMRDOY) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_MONTH: + RTCx->AMR &= (~RTC_AMR_AMRMON) & RTC_AMR_BITMASK; + break; + case RTC_TIMETYPE_YEAR: + RTCx->AMR &= (~RTC_AMR_AMRYEAR) & RTC_AMR_BITMASK; + break; + } + } + else + { + switch (AlarmTimeType) + { + case RTC_TIMETYPE_SECOND: + RTCx->AMR |= (RTC_AMR_AMRSEC); + break; + case RTC_TIMETYPE_MINUTE: + RTCx->AMR |= (RTC_AMR_AMRMIN); + break; + case RTC_TIMETYPE_HOUR: + RTCx->AMR |= (RTC_AMR_AMRHOUR); + break; + case RTC_TIMETYPE_DAYOFWEEK: + RTCx->AMR |= (RTC_AMR_AMRDOW); + break; + case RTC_TIMETYPE_DAYOFMONTH: + RTCx->AMR |= (RTC_AMR_AMRDOM); + break; + case RTC_TIMETYPE_DAYOFYEAR: + RTCx->AMR |= (RTC_AMR_AMRDOY); + break; + case RTC_TIMETYPE_MONTH: + RTCx->AMR |= (RTC_AMR_AMRMON); + break; + case RTC_TIMETYPE_YEAR: + RTCx->AMR |= (RTC_AMR_AMRYEAR); + break; + } + } +} + + +/*********************************************************************//** + * @brief Set current time value for each time type in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Timetype: Time Type, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @param[in] TimeValue Time value to set + * @return None + **********************************************************************/ +void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue) +{ + switch ( Timetype) + { + case RTC_TIMETYPE_SECOND: + if(TimeValue <= RTC_SECOND_MAX) + RTCx->SEC = TimeValue & RTC_SEC_MASK; + break; + + case RTC_TIMETYPE_MINUTE: + if(TimeValue <= RTC_MINUTE_MAX) + RTCx->MIN = TimeValue & RTC_MIN_MASK; + break; + + case RTC_TIMETYPE_HOUR: + if(TimeValue <= RTC_HOUR_MAX) + RTCx->HOUR = TimeValue & RTC_HOUR_MASK; + break; + + case RTC_TIMETYPE_DAYOFWEEK: + if(TimeValue <= RTC_DAYOFWEEK_MAX) + RTCx->DOW = TimeValue & RTC_DOW_MASK; + break; + + case RTC_TIMETYPE_DAYOFMONTH: + if((TimeValue >= RTC_DAYOFMONTH_MIN)&&(TimeValue <= RTC_DAYOFMONTH_MAX)) + RTCx->DOM = TimeValue & RTC_DOM_MASK; + break; + + case RTC_TIMETYPE_DAYOFYEAR: + if((TimeValue >= RTC_DAYOFYEAR_MIN)&&(TimeValue <= RTC_DAYOFYEAR_MAX)) + RTCx->DOY = TimeValue & RTC_DOY_MASK; + break; + + case RTC_TIMETYPE_MONTH: + if((TimeValue >= RTC_MONTH_MIN)&&(TimeValue <= RTC_MONTH_MAX)) + RTCx->MONTH = TimeValue & RTC_MONTH_MASK; + break; + + case RTC_TIMETYPE_YEAR: + if(TimeValue <= RTC_YEAR_MAX) + RTCx->YEAR = TimeValue & RTC_YEAR_MASK; + break; + } +} + +/*********************************************************************//** + * @brief Get current time value for each type time type + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Timetype: Time Type, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @return Value of time according to specified time type + **********************************************************************/ +uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype) +{ + switch (Timetype) + { + case RTC_TIMETYPE_SECOND: + return (RTCx->SEC & RTC_SEC_MASK); + case RTC_TIMETYPE_MINUTE: + return (RTCx->MIN & RTC_MIN_MASK); + case RTC_TIMETYPE_HOUR: + return (RTCx->HOUR & RTC_HOUR_MASK); + case RTC_TIMETYPE_DAYOFWEEK: + return (RTCx->DOW & RTC_DOW_MASK); + case RTC_TIMETYPE_DAYOFMONTH: + return (RTCx->DOM & RTC_DOM_MASK); + case RTC_TIMETYPE_DAYOFYEAR: + return (RTCx->DOY & RTC_DOY_MASK); + case RTC_TIMETYPE_MONTH: + return (RTCx->MONTH & RTC_MONTH_MASK); + case RTC_TIMETYPE_YEAR: + return (RTCx->YEAR & RTC_YEAR_MASK); + default: + return (0); + } +} + + +/*********************************************************************//** + * @brief Set full of time in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that + * contains time value in full. + * @return None + **********************************************************************/ +void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime) +{ + RTCx->DOM = pFullTime->DOM & RTC_DOM_MASK; + RTCx->DOW = pFullTime->DOW & RTC_DOW_MASK; + RTCx->DOY = pFullTime->DOY & RTC_DOY_MASK; + RTCx->HOUR = pFullTime->HOUR & RTC_HOUR_MASK; + RTCx->MIN = pFullTime->MIN & RTC_MIN_MASK; + RTCx->SEC = pFullTime->SEC & RTC_SEC_MASK; + RTCx->MONTH = pFullTime->MONTH & RTC_MONTH_MASK; + RTCx->YEAR = pFullTime->YEAR & RTC_YEAR_MASK; +} + + +/*********************************************************************//** + * @brief Get full of time in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that + * will be stored time in full. + * @return None + **********************************************************************/ +void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime) +{ + pFullTime->DOM = RTCx->DOM & RTC_DOM_MASK; + pFullTime->DOW = RTCx->DOW & RTC_DOW_MASK; + pFullTime->DOY = RTCx->DOY & RTC_DOY_MASK; + pFullTime->HOUR = RTCx->HOUR & RTC_HOUR_MASK; + pFullTime->MIN = RTCx->MIN & RTC_MIN_MASK; + pFullTime->SEC = RTCx->SEC & RTC_SEC_MASK; + pFullTime->MONTH = RTCx->MONTH & RTC_MONTH_MASK; + pFullTime->YEAR = RTCx->YEAR & RTC_YEAR_MASK; +} + + +/*********************************************************************//** + * @brief Set alarm time value for each time type + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Timetype: Time Type, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @param[in] ALValue Alarm time value to set + * @return None + **********************************************************************/ +void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue) +{ + switch (Timetype) + { + case RTC_TIMETYPE_SECOND: + if(ALValue <= RTC_SECOND_MAX) + RTCx->ALSEC = ALValue & RTC_SEC_MASK; + break; + + case RTC_TIMETYPE_MINUTE: + if(ALValue <= RTC_MINUTE_MAX) + RTCx->ALMIN = ALValue & RTC_MIN_MASK; + break; + + case RTC_TIMETYPE_HOUR: + if(ALValue <= RTC_HOUR_MAX) + RTCx->ALHOUR = ALValue & RTC_HOUR_MASK; + break; + + case RTC_TIMETYPE_DAYOFWEEK: + if(ALValue <= RTC_DAYOFWEEK_MAX) + RTCx->ALDOW = ALValue & RTC_DOW_MASK; + break; + + case RTC_TIMETYPE_DAYOFMONTH: + if((ALValue >= RTC_DAYOFMONTH_MIN)&&(ALValue <= RTC_DAYOFMONTH_MAX)) + RTCx->ALDOM = ALValue & RTC_DOM_MASK; + break; + + case RTC_TIMETYPE_DAYOFYEAR: + if((ALValue >= RTC_DAYOFYEAR_MIN)&&(ALValue <= RTC_DAYOFYEAR_MAX)) + RTCx->ALDOY = ALValue & RTC_DOY_MASK; + break; + + case RTC_TIMETYPE_MONTH: + if((ALValue >= RTC_MONTH_MIN)&&(ALValue <= RTC_MONTH_MAX)) + RTCx->ALMON = ALValue & RTC_MONTH_MASK; + break; + + case RTC_TIMETYPE_YEAR: + if(ALValue <= RTC_YEAR_MAX) + RTCx->ALYEAR = ALValue & RTC_YEAR_MASK; + break; + } +} + + + +/*********************************************************************//** + * @brief Get alarm time value for each time type + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Timetype: Time Type, should be: + * - RTC_TIMETYPE_SECOND + * - RTC_TIMETYPE_MINUTE + * - RTC_TIMETYPE_HOUR + * - RTC_TIMETYPE_DAYOFWEEK + * - RTC_TIMETYPE_DAYOFMONTH + * - RTC_TIMETYPE_DAYOFYEAR + * - RTC_TIMETYPE_MONTH + * - RTC_TIMETYPE_YEAR + * @return Value of Alarm time according to specified time type + **********************************************************************/ +uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype) +{ + switch (Timetype) + { + case RTC_TIMETYPE_SECOND: + return (RTCx->ALSEC & RTC_SEC_MASK); + case RTC_TIMETYPE_MINUTE: + return (RTCx->ALMIN & RTC_MIN_MASK); + case RTC_TIMETYPE_HOUR: + return (RTCx->ALHOUR & RTC_HOUR_MASK); + case RTC_TIMETYPE_DAYOFWEEK: + return (RTCx->ALDOW & RTC_DOW_MASK); + case RTC_TIMETYPE_DAYOFMONTH: + return (RTCx->ALDOM & RTC_DOM_MASK); + case RTC_TIMETYPE_DAYOFYEAR: + return (RTCx->ALDOY & RTC_DOY_MASK); + case RTC_TIMETYPE_MONTH: + return (RTCx->ALMON & RTC_MONTH_MASK); + case RTC_TIMETYPE_YEAR: + return (RTCx->ALYEAR & RTC_YEAR_MASK); + default: + return (0); + } +} + + +/*********************************************************************//** + * @brief Set full of alarm time in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that + * contains alarm time value in full. + * @return None + **********************************************************************/ +void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime) +{ + RTCx->ALDOM = pFullTime->DOM & RTC_DOM_MASK; + RTCx->ALDOW = pFullTime->DOW & RTC_DOW_MASK; + RTCx->ALDOY = pFullTime->DOY & RTC_DOY_MASK; + RTCx->ALHOUR = pFullTime->HOUR & RTC_HOUR_MASK; + RTCx->ALMIN = pFullTime->MIN & RTC_MIN_MASK; + RTCx->ALSEC = pFullTime->SEC & RTC_SEC_MASK; + RTCx->ALMON = pFullTime->MONTH & RTC_MONTH_MASK; + RTCx->ALYEAR = pFullTime->YEAR & RTC_YEAR_MASK; +} + + +/*********************************************************************//** + * @brief Get full of alarm time in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that + * will be stored alarm time in full. + * @return None + **********************************************************************/ +void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime) +{ + pFullTime->DOM = RTCx->ALDOM & RTC_DOM_MASK; + pFullTime->DOW = RTCx->ALDOW & RTC_DOW_MASK; + pFullTime->DOY = RTCx->ALDOY & RTC_DOY_MASK; + pFullTime->HOUR = RTCx->ALHOUR & RTC_HOUR_MASK; + pFullTime->MIN = RTCx->ALMIN & RTC_MIN_MASK; + pFullTime->SEC = RTCx->ALSEC & RTC_SEC_MASK; + pFullTime->MONTH = RTCx->ALMON & RTC_MONTH_MASK; + pFullTime->YEAR = RTCx->ALYEAR & RTC_YEAR_MASK; +} + + +/*********************************************************************//** + * @brief Check whether if specified Location interrupt in + * RTC peripheral is set or not + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] IntType Interrupt location type, should be: + * - RTC_INT_COUNTER_INCREASE: Counter Increment Interrupt + * block generated an interrupt. + * - RTC_INT_ALARM: Alarm generated an + * interrupt. + * @return New state of specified Location interrupt in RTC peripheral + * (SET or RESET) + **********************************************************************/ +IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType) +{ + return ((RTCx->ILR & IntType) ? SET : RESET); +} + + +/*********************************************************************//** + * @brief Clear specified Location interrupt pending in + * RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] IntType Interrupt location type, should be: + * - RTC_INT_COUNTER_INCREASE: Clear Counter Increment + * Interrupt pending. + * - RTC_INT_ALARM: Clear alarm interrupt pending + * @return None + **********************************************************************/ +void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType) +{ + RTCx->ILR |= IntType; +} + +/*********************************************************************//** + * @brief Enable/Disable calibration counter in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] NewState New State of this function, should be: + * - ENABLE: The calibration counter is enabled and counting + * - DISABLE: The calibration counter is disabled and reset to zero + * @return None + **********************************************************************/ +void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + RTCx->CCR &= (~RTC_CCR_CCALEN) & RTC_CCR_BITMASK; + } + else + { + RTCx->CCR |= RTC_CCR_CCALEN; + } +} + + +/*********************************************************************//** + * @brief Configures Calibration in RTC peripheral + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] CalibValue Calibration value, should be in range from + * 0 to 131,072 + * @param[in] CalibDir Calibration Direction, should be: + * - RTC_CALIB_DIR_FORWARD: Forward calibration + * - RTC_CALIB_DIR_BACKWARD: Backward calibration + * @return None + **********************************************************************/ +void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir) +{ + RTCx->CALIBRATION = ((CalibValue) & RTC_CALIBRATION_CALVAL_MASK) \ + | ((CalibDir == RTC_CALIB_DIR_BACKWARD) ? RTC_CALIBRATION_LIBDIR : 0); +} + + +/*********************************************************************//** + * @brief Write value to General purpose registers + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Channel General purpose registers Channel number, + * should be in range from 0 to 4. + * @param[in] Value Value to write + * @return None + * Note: These General purpose registers can be used to store important + * information when the main power supply is off. The value in these + * registers is not affected by chip reset. + **********************************************************************/ +void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value) +{ + uint32_t *preg; + + preg = (uint32_t *)&RTCx->GPREG0; + preg += Channel; + *preg = Value; +} + + +/*********************************************************************//** + * @brief Read value from General purpose registers + * @param[in] RTCx RTC peripheral selected, should be LPC_RTC + * @param[in] Channel General purpose registers Channel number, + * should be in range from 0 to 4. + * @return Read Value + * Note: These General purpose registers can be used to store important + * information when the main power supply is off. The value in these + * registers is not affected by chip reset. + **********************************************************************/ +uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel) +{ + uint32_t *preg; + uint32_t value; + + preg = (uint32_t *)&RTCx->GPREG0; + preg += Channel; + value = *preg; + return (value); +} +/*********************************************************************//** + * @brief Initialize an variable of type RTC_ER_CONFIG_Type. + * @param[in] pConfig The address of input variable. + * @return None + **********************************************************************/ +void RTC_ER_InitConfigStruct(RTC_ER_CONFIG_Type* pConfig) +{ + uint32_t tmp; + if(pConfig == NULL) + return; + + for(tmp = 0; tmp < RTC_ER_INPUT_CHANNEL_NUM; tmp++) + { + pConfig->InputChannel[tmp].EventOnPosEdge = FALSE; + pConfig->InputChannel[tmp].GPClear= FALSE; + pConfig->InputChannel[tmp].IntWake= FALSE; + } + pConfig->Clk = 64; +} + +/*********************************************************************//** + * @brief Initialize Event Monitor/Recorder + * @param[in] pConfig Configuration + * @return SUCCESS/ERROR + * Note: The RTC Module must be intialized before initializing this module. + **********************************************************************/ +Status RTC_ER_Init(RTC_ER_CONFIG_Type* pConfig) +{ + if(pConfig == NULL) + return ERROR; + if((LPC_RTC->CCR & RTC_CCR_CLKEN) == 0) + return ERROR; + + /* EV0 */ + if(pConfig->InputChannel[0].EventOnPosEdge) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV0_POS_EDGE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV0_POS_EDGE; + + if(pConfig->InputChannel[0].IntWake) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV0_INTWAKE_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV0_INTWAKE_ENABLE; + + if(pConfig->InputChannel[0].GPClear) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV0_GPCLEAR_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV0_GPCLEAR_ENABLE; + + /* EV1 */ + if(pConfig->InputChannel[1].EventOnPosEdge) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV1_POS_EDGE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV1_POS_EDGE; + + if(pConfig->InputChannel[1].IntWake) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV1_INTWAKE_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV1_INTWAKE_ENABLE; + + if(pConfig->InputChannel[1].GPClear) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV1_GPCLEAR_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV1_GPCLEAR_ENABLE; + + /* EV2 */ + if(pConfig->InputChannel[2].EventOnPosEdge) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV2_POS_EDGE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV2_POS_EDGE; + + if(pConfig->InputChannel[2].IntWake) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV2_INTWAKE_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV2_INTWAKE_ENABLE; + + if(pConfig->InputChannel[2].GPClear) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV2_GPCLEAR_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV2_GPCLEAR_ENABLE; + + /* Sample Clock */ + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_MODE_MASK; + switch(pConfig->Clk) + { + case 0: + LPC_RTC->ERCONTROL |= RTC_ERCTRL_MODE_CLK_DISABLE; + break; + case 16: + LPC_RTC->ERCONTROL |= RTC_ERCTRL_MODE_16HZ; + break; + case 64: + LPC_RTC->ERCONTROL |= RTC_ERCTRL_MODE_64HZ; + break; + case 1000: + LPC_RTC->ERCONTROL |= RTC_ERCTRL_MODE_1KHZ; + break; + default: + return ERROR; + } + return SUCCESS; +} +/*********************************************************************//** + * @brief Enable/Disable a input channel for Event Monitor/Recorder + * @param[in] channel Channel Number. It should be 0~2 + * @param[in]state ENABLE/DISABLE + * @return SUCCESS/ERROR + **********************************************************************/ +Status RTC_ER_Cmd(uint8_t channel, FunctionalState state) +{ + switch(channel) + { + case 0: + if(state) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV0_INPUT_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV0_INPUT_ENABLE; + break; + case 1: + if(state) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV1_INPUT_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV1_INPUT_ENABLE; + break; + case 2: + if(state) + LPC_RTC->ERCONTROL |= RTC_ERCTRL_EV2_INPUT_ENABLE; + else + LPC_RTC->ERCONTROL &= ~RTC_ERCTRL_EV2_INPUT_ENABLE; + break; + default: + return ERROR; + } + return SUCCESS; +} +/*********************************************************************//** + * @brief Get event count on a given channel. + * @param[in] channel Channel Number. It should be 0~2 + * @return counter + **********************************************************************/ +uint8_t RTC_ER_GetEventCount(uint8_t channel) +{ + uint8_t count = 0; + switch(channel) + { + case 0: + count = RTC_ER_EV0_COUNTER(LPC_RTC->ERCOUNTERS); + break; + case 1: + count = RTC_ER_EV1_COUNTER(LPC_RTC->ERCOUNTERS); + break; + case 2: + count = RTC_ER_EV2_COUNTER(LPC_RTC->ERCOUNTERS); + break; + default: + break; + } + return count; +} +/*********************************************************************//** + * @brief Get Event Monirot/Recorder Status. + * @param[in] None + * @return Status. It can includes: + * RTC_ER_EVENTS_ON_EV0_FLG + * RTC_ER_EVENTS_ON_EV1_FLG + * RTC_ER_EVENTS_ON_EV2_FLG + * RTC_ER_STATUS_GP_CLEARED_FLG + * RTC_ER_STATUS_WAKEUP_REQ_PENDING + **********************************************************************/ +uint32_t RTC_ER_GetStatus(void) +{ + return LPC_RTC->ERSTATUS; +} +/*********************************************************************//** + * @brief Clear Event Monitor/recoder status register. + * @param[in] status Status Flag. It should be: + * RTC_ER_EVENTS_ON_EV0_FLG + * RTC_ER_EVENTS_ON_EV1_FLG + * RTC_ER_EVENTS_ON_EV2_FLG + * RTC_ER_STATUS_GP_CLEARED_FLG + * RTC_ER_STATUS_WAKEUP_REQ_PENDING + * @return None + **********************************************************************/ +void RTC_ER_ClearStatus(uint32_t status) +{ + LPC_RTC->ERSTATUS |= status; +} +/*********************************************************************//** + * @brief Check whether a Wakup request is pending or not. + * @param[in] None + * @return TRUE/FALSE + **********************************************************************/ +Bool RTC_ER_WakupReqPending(void) +{ + if(LPC_RTC->ERSTATUS & RTC_ER_STATUS_WAKEUP_REQ_PENDING) + return TRUE; + else + return FALSE; +} +/*********************************************************************//** + * @brief Check whether RTC General Purpose registed has been cleared or not. + * @param[in] None + * @return TRUE/FALSE + **********************************************************************/ +Bool RTC_ER_GPCleared(void) +{ + if(LPC_RTC->ERSTATUS & RTC_ER_STATUS_GP_CLEARED_FLG) + return TRUE; + else + return FALSE; +} +/*********************************************************************//** + * @brief Get the timestamp of the fist event on a given channel. + * @param[in] channel Channel number (It should be 0~2) + * @param[in] pTimeStamp point to the buffer + * @return SUCCESS/ERROR + **********************************************************************/ +Status RTC_ER_GetFirstTimeStamp(uint8_t channel, RTC_ER_TIMESTAMP_Type* pTimeStamp) +{ + if(pTimeStamp == NULL) + return ERROR; + + switch(channel) + { + case 0: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERFIRSTSTAMP0); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERFIRSTSTAMP0); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERFIRSTSTAMP0); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERFIRSTSTAMP0); + break; + case 1: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERFIRSTSTAMP1); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERFIRSTSTAMP1); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERFIRSTSTAMP1); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERFIRSTSTAMP1); + break; + case 2: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERFIRSTSTAMP2); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERFIRSTSTAMP2); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERFIRSTSTAMP2); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERFIRSTSTAMP2); + break; + default: + break; + } + return SUCCESS; + +} +/*********************************************************************//** + * @brief Get the timestamp of the last event on a given channel. + * @param[in] channel Channel number (It should be 0~2) + * @param[in] pTimeStamp point to the buffer + * @return SUCCESS/ERROR + **********************************************************************/ +Status RTC_ER_GetLastTimeStamp(uint8_t channel, RTC_ER_TIMESTAMP_Type* pTimeStamp) +{ + if(pTimeStamp == NULL) + return ERROR; + + switch(channel) + { + case 0: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERLASTSTAMP0); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERLASTSTAMP0); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERLASTSTAMP0); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERLASTSTAMP0); + break; + case 1: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERLASTSTAMP1); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERLASTSTAMP1); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERLASTSTAMP1); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERLASTSTAMP1); + break; + case 2: + if((LPC_RTC->ERSTATUS & (1<SEC = RTC_ER_TIMESTAMP_SEC(LPC_RTC->ERLASTSTAMP2); + pTimeStamp->MIN= RTC_ER_TIMESTAMP_MIN(LPC_RTC->ERLASTSTAMP2); + pTimeStamp->HOUR= RTC_ER_TIMESTAMP_HOUR(LPC_RTC->ERLASTSTAMP2); + pTimeStamp->DOY = RTC_ER_TIMESTAMP_DOY(LPC_RTC->ERLASTSTAMP2); + break; + default: + break; + } + return SUCCESS; + +} + + +/** + * @} + */ + +#endif /*_RTC*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_ssp.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_ssp.c new file mode 100644 index 0000000000000000000000000000000000000000..f197e5b4e41fc3b6ca4a074480be547d9126e5f4 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_ssp.c @@ -0,0 +1,644 @@ +/********************************************************************** +* $Id$ lpc_ssp.c 2011-06-02 +*//** +* @file lpc_ssp.c +* @brief Contains all functions support for SSP firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup SSP + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _SSP + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_ssp.h" +#include "lpc_clkpwr.h" + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup SSP_Public_Functions + * @{ + */ +static void setSSPclock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock); + +/*********************************************************************//** + * @brief Setup clock rate for SSP device + * @param[in] SSPx SSP peripheral definition, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] target_clock : clock of SSP (Hz) + * @return None + ***********************************************************************/ +static void setSSPclock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock) +{ + uint32_t prescale, cr0_div, cmp_clk, ssp_clk; + ssp_clk = CLKPWR_GetCLK (CLKPWR_CLKTYPE_PER); + + /* Find closest divider to get at or under the target frequency. + Use smallest prescale possible and rely on the divider to get + the closest target frequency */ + cr0_div = 0; + cmp_clk = 0xFFFFFFFF; + prescale = 2; + while (cmp_clk > target_clock) + { + cmp_clk = ssp_clk / ((cr0_div + 1) * prescale); + if (cmp_clk > target_clock) + { + cr0_div++; + if (cr0_div > 0xFF) + { + cr0_div = 0; + prescale += 2; + } + } + } + + /* Write computed prescaler and divider back to register */ + SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK; + SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK; + SSPx->CPSR = prescale & SSP_CPSR_BITMASK; +} + +/** + * @} + */ + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup SSP_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initializes the SSPx peripheral according to the specified +* parameters in the SSP_ConfigStruct. + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] SSP_ConfigStruct Pointer to a SSP_CFG_Type structure +* that contains the configuration information for the +* specified SSP peripheral. + * @return None + *********************************************************************/ +void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct) +{ + uint32_t tmp; + + if(SSPx == LPC_SSP0) { + /* Set up clock and power for SSP0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, ENABLE); + } else if(SSPx == LPC_SSP1) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, ENABLE); + } else if(SSPx == LPC_SSP2) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP2, ENABLE); + } else { + return; + } + + /* Configure SSP, interrupt is disable, LoopBack mode is disable, + * SSP is disable, Slave output is disable as default + */ + tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \ + | (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit)) + & SSP_CR0_BITMASK; + // write back to SSP control register + SSPx->CR0 = tmp; + + tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK; + // Write back to CR1 + SSPx->CR1 = tmp; + + // Set clock rate for SSP peripheral + setSSPclock(SSPx, SSP_ConfigStruct->ClockRate); +} + +/*********************************************************************//** + * @brief De-initializes the SSPx peripheral registers to their +* default reset values. + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @return None + **********************************************************************/ +void SSP_DeInit(LPC_SSP_TypeDef* SSPx) +{ + if (SSPx == LPC_SSP0){ + /* Set up clock and power for SSP0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, DISABLE); + } else if (SSPx == LPC_SSP1) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, DISABLE); + } else if (SSPx == LPC_SSP2) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP2, DISABLE); + } +} + +/*****************************************************************************//** +* @brief Get data size bit selected +* @param[in] SSPx pointer to LPC_SSP_TypeDef structure, should be: +* - LPC_SSP0: SSP0 peripheral +* - LPC_SSP1: SSP1 peripheral +* @return Data size, could be: +* - SSP_DATABIT_4: 4 bit transfer +* - SSP_DATABIT_5: 5 bit transfer +* ... +* - SSP_DATABIT_16: 16 bit transfer +*******************************************************************************/ +uint8_t SSP_GetDataSize(LPC_SSP_TypeDef* SSPx) +{ + return (SSPx->CR0 & (0xF)); +} + +/*****************************************************************************//** +* @brief Fills each SSP_InitStruct member with its default value: +* - CPHA = SSP_CPHA_FIRST +* - CPOL = SSP_CPOL_HI +* - ClockRate = 1000000 +* - Databit = SSP_DATABIT_8 +* - Mode = SSP_MASTER_MODE +* - FrameFormat = SSP_FRAME_SSP +* @param[in] SSP_InitStruct Pointer to a SSP_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct) +{ + SSP_InitStruct->CPHA = SSP_CPHA_FIRST; + SSP_InitStruct->CPOL = SSP_CPOL_HI; + SSP_InitStruct->ClockRate = 1000000; + SSP_InitStruct->Databit = SSP_DATABIT_8; + SSP_InitStruct->Mode = SSP_MASTER_MODE; + SSP_InitStruct->FrameFormat = SSP_FRAME_SPI; +} + + +/*********************************************************************//** + * @brief Enable or disable SSP peripheral's operation + * @param[in] SSPx SSP peripheral, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] NewState New State of SSPx peripheral's operation + * @return none + **********************************************************************/ +void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + SSPx->CR1 |= SSP_CR1_SSP_EN; + } + else + { + SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK; + } +} + +/*********************************************************************//** + * @brief Enable or disable Loop Back mode function in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] NewState New State of Loop Back mode, should be: + * - ENABLE: Enable this function + * - DISABLE: Disable this function + * @return None + **********************************************************************/ +void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + SSPx->CR1 |= SSP_CR1_LBM_EN; + } + else + { + SSPx->CR1 &= (~SSP_CR1_LBM_EN) & SSP_CR1_BITMASK; + } +} + +/*********************************************************************//** + * @brief Enable or disable Slave Output function in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] NewState New State of Slave Output function, should be: + * - ENABLE: Slave Output in normal operation + * - DISABLE: Slave Output is disabled. This blocks + * SSP controller from driving the transmit data + * line (MISO) + * Note: This function is available when SSP peripheral in Slave mode + * @return None + **********************************************************************/ +void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + SSPx->CR1 &= (~SSP_CR1_SO_DISABLE) & SSP_CR1_BITMASK; + } + else + { + SSPx->CR1 |= SSP_CR1_SO_DISABLE; + } +} + + + +/*********************************************************************//** + * @brief Transmit a single data through SSPx peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] Data Data to transmit (must be 16 or 8-bit long, + * this depend on SSP data bit number configured) + * @return none + **********************************************************************/ +void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data) +{ + SSPx->DR = SSP_DR_BITMASK(Data); +} + + + +/*********************************************************************//** + * @brief Receive a single data from SSPx peripheral + * @param[in] SSPx SSP peripheral selected, should be + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @return Data received (16-bit long) + **********************************************************************/ +uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx) +{ + return ((uint16_t) (SSP_DR_BITMASK(SSPx->DR))); +} + +/*********************************************************************//** + * @brief SSP Read write data function + * @param[in] SSPx Pointer to SSP peripheral, should be + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] dataCfg Pointer to a SSP_DATA_SETUP_Type structure that + * contains specified information about transmit + * data configuration. + * @param[in] xfType Transfer type, should be: + * - SSP_TRANSFER_POLLING: Polling mode + * - SSP_TRANSFER_INTERRUPT: Interrupt mode + * @return Actual Data length has been transferred in polling mode. + * In interrupt mode, always return (0) + * Return (-1) if error. + * Note: This function can be used in both master and slave mode. + ***********************************************************************/ +int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \ + SSP_TRANSFER_Type xfType) +{ + uint8_t *rdata8; + uint8_t *wdata8; + uint16_t *rdata16; + uint16_t *wdata16; + uint32_t stat; + uint32_t tmp; + int32_t dataword; + + dataCfg->rx_cnt = 0; + dataCfg->tx_cnt = 0; + dataCfg->status = 0; + + + /* Clear all remaining data in RX FIFO */ + while (SSPx->SR & SSP_SR_RNE){ + tmp = (uint32_t) SSP_ReceiveData(SSPx); + } + + // Clear status + SSPx->ICR = SSP_ICR_BITMASK; + if(SSP_GetDataSize(SSPx)>SSP_DATABIT_8) + dataword = 1; + else dataword = 0; + + // Polling mode ---------------------------------------------------------------------- + if (xfType == SSP_TRANSFER_POLLING){ + if (dataword == 0){ + rdata8 = (uint8_t *)dataCfg->rx_data; + wdata8 = (uint8_t *)dataCfg->tx_data; + } else { + rdata16 = (uint16_t *)dataCfg->rx_data; + wdata16 = (uint16_t *)dataCfg->tx_data; + } + while ((dataCfg->tx_cnt < dataCfg->length) || (dataCfg->rx_cnt < dataCfg->length)){ + if ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt < dataCfg->length)){ + // Write data to buffer + if(dataCfg->tx_data == NULL){ + if (dataword == 0){ + SSP_SendData(SSPx, 0xFF); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, 0xFFFF); + dataCfg->tx_cnt += 2; + } + } else { + if (dataword == 0){ + SSP_SendData(SSPx, *wdata8); + wdata8++; + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, *wdata16); + wdata16++; + dataCfg->tx_cnt += 2; + } + } + } + + // Check overrun error + if ((stat = SSPx->RIS) & SSP_RIS_ROR){ + // save status and return + dataCfg->status = stat | SSP_STAT_ERROR; + return (-1); + } + + // Check for any data available in RX FIFO + while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt < dataCfg->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (dataCfg->rx_data != NULL) + { + if (dataword == 0){ + *(rdata8) = (uint8_t) tmp; + rdata8++; + } else { + *(rdata16) = (uint16_t) tmp; + rdata16++; + } + } + // Increase counter + if (dataword == 0){ + dataCfg->rx_cnt++; + } else { + dataCfg->rx_cnt += 2; + } + } + } + + // save status + dataCfg->status = SSP_STAT_DONE; + + if (dataCfg->tx_data != NULL){ + return dataCfg->tx_cnt; + } else if (dataCfg->rx_data != NULL){ + return dataCfg->rx_cnt; + } else { + return (0); + } + } + + // Interrupt mode ---------------------------------------------------------------------- + else if (xfType == SSP_TRANSFER_INTERRUPT){ + + while ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt < dataCfg->length)){ + // Write data to buffer + if(dataCfg->tx_data == NULL){ + if (dataword == 0){ + SSP_SendData(SSPx, 0xFF); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, 0xFFFF); + dataCfg->tx_cnt += 2; + } + } else { + if (dataword == 0){ + SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt))); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt))); + dataCfg->tx_cnt += 2; + } + } + + // Check error + if ((stat = SSPx->RIS) & SSP_RIS_ROR){ + // save status and return + dataCfg->status = stat | SSP_STAT_ERROR; + return (-1); + } + + // Check for any data available in RX FIFO + while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt < dataCfg->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (dataCfg->rx_data != NULL) + { + if (dataword == 0){ + *(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp; + } else { + *(uint16_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint16_t) tmp; + } + } + // Increase counter + if (dataword == 0){ + dataCfg->rx_cnt++; + } else { + dataCfg->rx_cnt += 2; + } + } + } + + // If there more data to sent or receive + if ((dataCfg->rx_cnt < dataCfg->length) || (dataCfg->tx_cnt < dataCfg->length)){ + // Enable all interrupt + SSPx->IMSC = SSP_IMSC_BITMASK; + } else { + // Save status + dataCfg->status = SSP_STAT_DONE; + } + return (0); + } + + return (-1); +} + +/*********************************************************************//** + * @brief Checks whether the specified SSP status flag is set or not + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] FlagType Type of flag to check status, should be one + * of following: + * - SSP_STAT_TXFIFO_EMPTY: TX FIFO is empty + * - SSP_STAT_TXFIFO_NOTFULL: TX FIFO is not full + * - SSP_STAT_RXFIFO_NOTEMPTY: RX FIFO is not empty + * - SSP_STAT_RXFIFO_FULL: RX FIFO is full + * - SSP_STAT_BUSY: SSP peripheral is busy + * @return New State of specified SSP status flag + **********************************************************************/ +FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType) +{ + return ((SSPx->SR & FlagType) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Enable or disable specified interrupt type in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] IntType Interrupt type in SSP peripheral, should be: + * - SSP_INTCFG_ROR: Receive Overrun interrupt + * - SSP_INTCFG_RT: Receive Time out interrupt + * - SSP_INTCFG_RX: RX FIFO is at least half full interrupt + * - SSP_INTCFG_TX: TX FIFO is at least half empty interrupt + * @param[in] NewState New State of specified interrupt type, should be: + * - ENABLE: Enable this interrupt type + * - DISABLE: Disable this interrupt type + * @return None + * Note: We can enable/disable multi-interrupt type by OR multi value + **********************************************************************/ +void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + SSPx->IMSC |= IntType; + } + else + { + SSPx->IMSC &= (~IntType) & SSP_IMSC_BITMASK; + } +} + +/*********************************************************************//** + * @brief Check whether the specified Raw interrupt status flag is + * set or not + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] RawIntType Raw Interrupt Type, should be: + * - SSP_INTSTAT_RAW_ROR: Receive Overrun interrupt + * - SSP_INTSTAT_RAW_RT: Receive Time out interrupt + * - SSP_INTSTAT_RAW_RX: RX FIFO is at least half full interrupt + * - SSP_INTSTAT_RAW_TX: TX FIFO is at least half empty interrupt + * @return New State of specified Raw interrupt status flag in SSP peripheral + * Note: Enabling/Disabling specified interrupt in SSP peripheral does not + * effect to Raw Interrupt Status flag. + **********************************************************************/ +IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType) +{ + return ((SSPx->RIS & RawIntType) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Get Raw Interrupt Status register + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @return Raw Interrupt Status (RIS) register value + **********************************************************************/ +uint32_t SSP_GetRawIntStatusReg(LPC_SSP_TypeDef *SSPx) +{ + return (SSPx->RIS); +} + +/*********************************************************************//** + * @brief Check whether the specified interrupt status flag is + * set or not + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] IntType Raw Interrupt Type, should be: + * - SSP_INTSTAT_ROR: Receive Overrun interrupt + * - SSP_INTSTAT_RT: Receive Time out interrupt + * - SSP_INTSTAT_RX: RX FIFO is at least half full interrupt + * - SSP_INTSTAT_TX: TX FIFO is at least half empty interrupt + * @return New State of specified interrupt status flag in SSP peripheral + * Note: Enabling/Disabling specified interrupt in SSP peripheral effects + * to Interrupt Status flag. + **********************************************************************/ +IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType) +{ + return ((SSPx->MIS & IntType) ? SET :RESET); +} + +/*********************************************************************//** + * @brief Clear specified interrupt pending in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] IntType Interrupt pending to clear, should be: + * - SSP_INTCLR_ROR: clears the "frame was received when + * RxFIFO was full" interrupt. + * - SSP_INTCLR_RT: clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt. + * @return None + **********************************************************************/ +void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType) +{ + SSPx->ICR = IntType; +} + +/*********************************************************************//** + * @brief Enable/Disable DMA function for SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be: + * - LPC_SSP0: SSP0 peripheral + * - LPC_SSP1: SSP1 peripheral + * @param[in] DMAMode Type of DMA, should be: + * - SSP_DMA_TX: DMA for the transmit FIFO + * - SSP_DMA_RX: DMA for the Receive FIFO + * @param[in] NewState New State of DMA function on SSP peripheral, + * should be: + * - ENALBE: Enable this function + * - DISABLE: Disable this function + * @return None + **********************************************************************/ +void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + SSPx->DMACR |= DMAMode; + } + else + { + SSPx->DMACR &= (~DMAMode) & SSP_DMA_BITMASK; + } +} + +/** + * @} + */ + +#endif /*_SSP*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_systick.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_systick.c new file mode 100644 index 0000000000000000000000000000000000000000..66ea6d870aada8867d58da600a37b6941536cdd9 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_systick.c @@ -0,0 +1,192 @@ +/********************************************************************** +* $Id$ lpc_systick.c 2011-06-02 +*//** +* @file lpc_systick.c +* @brief Contains all functions support for SysTick firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup SYSTICK + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _SYSTICK + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_systick.h" +#include "lpc_clkpwr.h" + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup SYSTICK_Public_Functions + * @{ + */ +/*********************************************************************//** + * @brief Initial System Tick with using internal CPU clock source + * @param[in] time time interval(ms) + * @return None + * Note: time interval parameter should be less than: + * 1/cclk * (2^24) * 1000 (ms) + * In this case, with cclk = 96Mhz, time interval value < 174ms + **********************************************************************/ +void SYSTICK_InternalInit(uint32_t time) +{ + uint32_t cclk; + float maxtime; + + cclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU); + + /* With internal CPU clock frequency for LPC178X is 'SystemCoreClock' + * And limit 24 bit for RELOAD value + * So the maximum time can be set: + * 1/SystemCoreClock * (2^24) * 1000 (ms) + */ + //check time value is available or not + maxtime = (1<<24)/(cclk / 1000) ; + + if(time > maxtime) + { + //Error loop + while(1); + } + else + { + //Select CPU clock is System Tick clock source + SysTick->CTRL |= ST_CTRL_CLKSOURCE; + + /* Set RELOAD value + * RELOAD = (SystemCoreClock/1000) * time - 1 + * with time base is millisecond + */ + SysTick->LOAD = (cclk/1000)*time - 1; + } +} + +/*********************************************************************//** + * @brief Initial System Tick with using external clock source + * @param[in] freq external clock frequency(Hz) + * @param[in] time time interval(ms) + * @return None + **********************************************************************/ +void SYSTICK_ExternalInit(uint32_t freq, uint32_t time) +{ + float maxtime; + + /* With external clock frequency for LPC178X is 'freq' + * And limit 24 bit for RELOAD value + * So the maximum time can be set: + * 1/freq * (2^24) * 1000 (ms) + */ + //check time value is available or not + maxtime = (1<<24)/(freq / 1000) ; + if (time>maxtime) + { + //Error Loop + while(1); + } + else + { + //Select external clock is System Tick clock source + SysTick->CTRL &= ~ ST_CTRL_CLKSOURCE; + + /* Set RELOAD value + * RELOAD = (freq/1000) * time - 1 + * with time base is millisecond + */ + maxtime = (freq/1000)*time - 1; + SysTick->LOAD = (freq/1000)*time - 1; + } +} + +/*********************************************************************//** + * @brief Enable/disable System Tick counter + * @param[in] NewState System Tick counter status, should be: + * - ENABLE + * - DISABLE + * @return None + **********************************************************************/ +void SYSTICK_Cmd(FunctionalState NewState) +{ + if(NewState == ENABLE) + //Enable System Tick counter + SysTick->CTRL |= ST_CTRL_ENABLE; + else + //Disable System Tick counter + SysTick->CTRL &= ~ST_CTRL_ENABLE; +} + +/*********************************************************************//** + * @brief Enable/disable System Tick interrupt + * @param[in] NewState System Tick interrupt status, should be: + * - ENABLE + * - DISABLE + * @return None + **********************************************************************/ +void SYSTICK_IntCmd(FunctionalState NewState) +{ + if(NewState == ENABLE) + //Enable System Tick counter + SysTick->CTRL |= ST_CTRL_TICKINT; + else + //Disable System Tick counter + SysTick->CTRL &= ~ST_CTRL_TICKINT; +} + +/*********************************************************************//** + * @brief Get current value of System Tick counter + * @param[in] None + * @return current value of System Tick counter + **********************************************************************/ +uint32_t SYSTICK_GetCurrentValue(void) +{ + return (SysTick->VAL); +} + +/*********************************************************************//** + * @brief Clear Counter flag + * @param[in] None + * @return None + **********************************************************************/ +void SYSTICK_ClearCounterFlag(void) +{ + SysTick->CTRL &= ~ST_CTRL_COUNTFLAG; +} +/** + * @} + */ +#endif /*_SYSTICK*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_timer.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..dee26cc13ce9f1ce9424f16261631bc320cefc71 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_timer.c @@ -0,0 +1,582 @@ +/********************************************************************** +* $Id$ lpc_timer.c 2011-06-02 +*//** +* @file lpc_timer.c +* @brief Contains all functions support for Timer firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup TIMER + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _TIM + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_timer.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + +/* Private Functions ---------------------------------------------------------- */ + +static uint32_t getPClock (uint32_t timernum); +static uint32_t converUSecToVal (uint32_t timernum, uint32_t usec); +static int32_t converPtrToTimeNum (LPC_TIM_TypeDef *TIMx); + + +/*********************************************************************//** + * @brief Get peripheral clock of each timer controller + * @param[in] timernum Timer number + * @return Peripheral clock of timer + **********************************************************************/ +static uint32_t getPClock (uint32_t timernum) +{ + uint32_t clkdlycnt; + clkdlycnt = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + return clkdlycnt; +} + + +/*********************************************************************//** + * @brief Convert a time to a timer count value + * @param[in] timernum Timer number + * @param[in] usec Time in microseconds + * @return The number of required clock ticks to give the time delay + **********************************************************************/ +uint32_t converUSecToVal (uint32_t timernum, uint32_t usec) +{ + uint64_t clkdlycnt; + + // Get Pclock of timer + clkdlycnt = (uint64_t) getPClock(timernum); + + clkdlycnt = (clkdlycnt * usec) / 1000000; + return (uint32_t) clkdlycnt; +} + + +/*********************************************************************//** + * @brief Convert a timer register pointer to a timer number + * @param[in] TIMx Pointer to LPC_TIM_TypeDef, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @return The timer number (0 to 3) or -1 if register pointer is bad + **********************************************************************/ +int32_t converPtrToTimeNum (LPC_TIM_TypeDef *TIMx) +{ + int32_t tnum = -1; + + if (TIMx == LPC_TIM0) + { + tnum = 0; + } + else if (TIMx == LPC_TIM1) + { + tnum = 1; + } + else if (TIMx == LPC_TIM2) + { + tnum = 2; + } + else if (TIMx == LPC_TIM3) + { + tnum = 3; + } + + return tnum; +} + +/* End of Private Functions ---------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup TIM_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Get Interrupt Status + * @param[in] TIMx Timer selection, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] IntFlag Interrupt type, should be: + * - TIM_MR0_INT: Interrupt for Match channel 0 + * - TIM_MR1_INT: Interrupt for Match channel 1 + * - TIM_MR2_INT: Interrupt for Match channel 2 + * - TIM_MR3_INT: Interrupt for Match channel 3 + * - TIM_CR0_INT: Interrupt for Capture channel 0 + * - TIM_CR1_INT: Interrupt for Capture channel 1 + * @return Flag Status for required interrupt + * - SET : interrupt + * - RESET : no interrupt + **********************************************************************/ +FlagStatus TIM_GetIntStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag) +{ + uint8_t temp; + temp = (TIMx->IR)& TIM_IR_CLR(IntFlag); + if (temp) + return SET; + + return RESET; + +} +/*********************************************************************//** + * @brief Get Capture Interrupt Status + * @param[in] TIMx Timer selection, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] IntFlag: interrupt type, should be: + * - TIM_MR0_INT: Interrupt for Match channel 0 + * - TIM_MR1_INT: Interrupt for Match channel 1 + * - TIM_MR2_INT: Interrupt for Match channel 2 + * - TIM_MR3_INT: Interrupt for Match channel 3 + * - TIM_CR0_INT: Interrupt for Capture channel 0 + * - TIM_CR1_INT: Interrupt for Capture channel 1 + * @return FlagStatus + * - SET : interrupt + * - RESET : no interrupt + **********************************************************************/ +FlagStatus TIM_GetIntCaptureStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag) +{ + uint8_t temp; + temp = (TIMx->IR) & (1<<(4+IntFlag)); + if(temp) + return SET; + return RESET; +} +/*********************************************************************//** + * @brief Clear Interrupt pending + * @param[in] TIMx Timer selection, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] IntFlag: interrupt type, should be: + * - TIM_MR0_INT: Interrupt for Match channel 0 + * - TIM_MR1_INT: Interrupt for Match channel 1 + * - TIM_MR2_INT: Interrupt for Match channel 2 + * - TIM_MR3_INT: Interrupt for Match channel 3 + * - TIM_CR0_INT: Interrupt for Capture channel 0 + * - TIM_CR1_INT: Interrupt for Capture channel 1 + * @return None + **********************************************************************/ +void TIM_ClearIntPending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag) +{ + TIMx->IR = TIM_IR_CLR(IntFlag); +} + +/*********************************************************************//** + * @brief Clear Capture Interrupt pending + * @param[in] TIMx Timer selection, should be + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] IntFlag interrupt type, should be: + * - TIM_MR0_INT: Interrupt for Match channel 0 + * - TIM_MR1_INT: Interrupt for Match channel 1 + * - TIM_MR2_INT: Interrupt for Match channel 2 + * - TIM_MR3_INT: Interrupt for Match channel 3 + * - TIM_CR0_INT: Interrupt for Capture channel 0 + * - TIM_CR1_INT: Interrupt for Capture channel 1 + * @return None + **********************************************************************/ +void TIM_ClearIntCapturePending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag) +{ + TIMx->IR = (1<<(4+IntFlag)); +} + +/*********************************************************************//** + * @brief Configuration for Timer at initial time + * @param[in] TimerCounterMode timer counter mode, should be: + * - TIM_TIMER_MODE: Timer mode + * - TIM_COUNTER_RISING_MODE: Counter rising mode + * - TIM_COUNTER_FALLING_MODE: Counter falling mode + * - TIM_COUNTER_ANY_MODE:Counter on both edges + * @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type or + * TIM_COUNTERCFG_Type + * @return None + **********************************************************************/ +void TIM_ConfigStructInit(TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct) +{ + if (TimerCounterMode == TIM_TIMER_MODE ) + { + TIM_TIMERCFG_Type * pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct; + pTimeCfg->PrescaleOption = TIM_PRESCALE_USVAL; + pTimeCfg->PrescaleValue = 1; + } + else + { + TIM_COUNTERCFG_Type * pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct; + pCounterCfg->CountInputSelect = TIM_COUNTER_INCAP0; + } +} + +/*********************************************************************//** + * @brief Initial Timer/Counter device + * Set Clock frequency for Timer + * Set initial configuration for Timer + * @param[in] TIMx Timer selection, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] TimerCounterMode Timer counter mode, should be: + * - TIM_TIMER_MODE: Timer mode + * - TIM_COUNTER_RISING_MODE: Counter rising mode + * - TIM_COUNTER_FALLING_MODE: Counter falling mode + * - TIM_COUNTER_ANY_MODE:Counter on both edges + * @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type + * that contains the configuration information for the + * specified Timer peripheral. + * @return None + **********************************************************************/ +void TIM_Init(LPC_TIM_TypeDef *TIMx, TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct) +{ + TIM_TIMERCFG_Type *pTimeCfg; + TIM_COUNTERCFG_Type *pCounterCfg; + + //set power + if (TIMx== LPC_TIM0) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM0, ENABLE); + } + else if (TIMx== LPC_TIM1) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM1, ENABLE); + } + + else if (TIMx== LPC_TIM2) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, ENABLE); + } + else if (TIMx== LPC_TIM3) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM3, ENABLE); + } + + TIMx->CTCR &= ~TIM_CTCR_MODE_MASK; + TIMx->CTCR |= TIM_TIMER_MODE; + + TIMx->TC =0; + TIMx->PC =0; + TIMx->PR =0; + TIMx->TCR |= (1<<1); //Reset Counter + TIMx->TCR &= ~(1<<1); //release reset + if (TimerCounterMode == TIM_TIMER_MODE ) + { + pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct; + if (pTimeCfg->PrescaleOption == TIM_PRESCALE_TICKVAL) + { + TIMx->PR = pTimeCfg->PrescaleValue -1 ; + } + else + { + TIMx->PR = converUSecToVal (converPtrToTimeNum(TIMx),pTimeCfg->PrescaleValue)-1; + } + } + else + { + + pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct; + TIMx->CTCR &= ~TIM_CTCR_INPUT_MASK; + if (pCounterCfg->CountInputSelect == TIM_COUNTER_INCAP1) + TIMx->CCR |= _BIT(2); + } + + // Clear interrupt pending + TIMx->IR = 0xFFFFFFFF; + +} + +/*********************************************************************//** + * @brief Close Timer/Counter device + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @return None + **********************************************************************/ +void TIM_DeInit (LPC_TIM_TypeDef *TIMx) +{ + // Disable timer/counter + TIMx->TCR = 0x00; + + // Disable power + if (TIMx== LPC_TIM0) + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM0, DISABLE); + + else if (TIMx== LPC_TIM1) + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM1, DISABLE); + + else if (TIMx== LPC_TIM2) + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, DISABLE); + + else if (TIMx== LPC_TIM3) + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, DISABLE); + +} + +/*********************************************************************//** + * @brief Start/Stop Timer/Counter device + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] NewState + * - ENABLE : set timer enable + * - DISABLE : disable timer + * @return None + **********************************************************************/ +void TIM_Cmd(LPC_TIM_TypeDef *TIMx, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + TIMx->TCR |= TIM_ENABLE; + } + else + { + TIMx->TCR &= ~TIM_ENABLE; + } +} + +/*********************************************************************//** + * @brief Reset Timer/Counter device, + * Make TC and PC are synchronously reset on the next + * positive edge of PCLK + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @return None + **********************************************************************/ +void TIM_ResetCounter(LPC_TIM_TypeDef *TIMx) +{ + TIMx->TCR |= TIM_RESET; + TIMx->TCR &= ~TIM_RESET; +} + +/*********************************************************************//** + * @brief Configuration for Match register + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] TIM_MatchConfigStruct Pointer to TIM_MATCHCFG_Type + * - MatchChannel : choose channel 0 or 1 + * - IntOnMatch : if SET, interrupt will be generated when MRxx match + * the value in TC + * - StopOnMatch : if SET, TC and PC will be stopped whenM Rxx match + * the value in TC + * - ResetOnMatch : if SET, Reset on MR0 when MRxx match + * the value in TC + * -ExtMatchOutputType: Select output for external match + * + 0: Do nothing for external output pin if match + * + 1: Force external output pin to low if match + * + 2: Force external output pin to high if match + * + 3: Toggle external output pin if match + * MatchValue: Set the value to be compared with TC value + * @return None + **********************************************************************/ +void TIM_ConfigMatch(LPC_TIM_TypeDef *TIMx, TIM_MATCHCFG_Type *TIM_MatchConfigStruct) +{ + switch(TIM_MatchConfigStruct->MatchChannel) + { + case 0: + TIMx->MR0 = TIM_MatchConfigStruct->MatchValue; + break; + case 1: + TIMx->MR1 = TIM_MatchConfigStruct->MatchValue; + break; + case 2: + TIMx->MR2 = TIM_MatchConfigStruct->MatchValue; + break; + case 3: + TIMx->MR3 = TIM_MatchConfigStruct->MatchValue; + break; + default: + //Error match value + //Error loop + while(1); + } + //interrupt on MRn + TIMx->MCR &= ~ TIM_MCR_CHANNEL_MASKBIT(TIM_MatchConfigStruct->MatchChannel); + + if (TIM_MatchConfigStruct->IntOnMatch) + TIMx->MCR |= TIM_INT_ON_MATCH(TIM_MatchConfigStruct->MatchChannel); + + //reset on MRn + if (TIM_MatchConfigStruct->ResetOnMatch) + TIMx->MCR |= TIM_RESET_ON_MATCH(TIM_MatchConfigStruct->MatchChannel); + + //stop on MRn + if (TIM_MatchConfigStruct->StopOnMatch) + TIMx->MCR |= TIM_STOP_ON_MATCH(TIM_MatchConfigStruct->MatchChannel); + + // match output type + + TIMx->EMR &= ~ TIM_EM_MASK(TIM_MatchConfigStruct->MatchChannel); + TIMx->EMR |= TIM_EM_SET(TIM_MatchConfigStruct->MatchChannel,TIM_MatchConfigStruct->ExtMatchOutputType); +} +/*********************************************************************//** + * @brief Update Match value + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] MatchChannel Match channel, should be: 0..3 + * @param[in] MatchValue updated match value + * @return None + **********************************************************************/ +void TIM_UpdateMatchValue(LPC_TIM_TypeDef *TIMx,uint8_t MatchChannel, uint32_t MatchValue) +{ + switch(MatchChannel) + { + case 0: + TIMx->MR0 = MatchValue; + break; + case 1: + TIMx->MR1 = MatchValue; + break; + case 2: + TIMx->MR2 = MatchValue; + break; + case 3: + TIMx->MR3 = MatchValue; + break; + default: + //Error Loop + while(1); + } +} + +/*********************************************************************//** + * @brief Configuration for Capture register + * @param[in] TIMx Pointer to timer device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] TIM_CaptureConfigStruct Pointer to TIM_CAPTURECFG_Type + * - CaptureChannel: set the channel to capture data + * - RisingEdge : if SET, Capture at rising edge + * - FallingEdge : if SET, Capture at falling edge + * - IntOnCaption : if SET, Capture generate interrupt + * @return None + **********************************************************************/ +void TIM_ConfigCapture(LPC_TIM_TypeDef *TIMx, TIM_CAPTURECFG_Type *TIM_CaptureConfigStruct) +{ + TIMx->CCR &= ~TIM_CCR_CHANNEL_MASKBIT(TIM_CaptureConfigStruct->CaptureChannel); + + if (TIM_CaptureConfigStruct->RisingEdge) + TIMx->CCR |= TIM_CAP_RISING(TIM_CaptureConfigStruct->CaptureChannel); + + if (TIM_CaptureConfigStruct->FallingEdge) + TIMx->CCR |= TIM_CAP_FALLING(TIM_CaptureConfigStruct->CaptureChannel); + + if (TIM_CaptureConfigStruct->IntOnCaption) + TIMx->CCR |= TIM_INT_ON_CAP(TIM_CaptureConfigStruct->CaptureChannel); +} + +/*********************************************************************//** + * @brief Read value of capture register in timer/counter device + * @param[in] TIMx Pointer to timer/counter device, should be: + * - LPC_TIM0: TIMER0 peripheral + * - LPC_TIM1: TIMER1 peripheral + * - LPC_TIM2: TIMER2 peripheral + * - LPC_TIM3: TIMER3 peripheral + * @param[in] CaptureChannel: capture channel number, should be: + * - TIM_COUNTER_INCAP0: CAPn.0 input pin for TIMERn + * - TIM_COUNTER_INCAP1: CAPn.1 input pin for TIMERn + * @return Value of capture register + **********************************************************************/ +uint32_t TIM_GetCaptureValue(LPC_TIM_TypeDef *TIMx, TIM_COUNTER_INPUT_OPT CaptureChannel) +{ + if(CaptureChannel==0) + return TIMx->CR0; + else + return TIMx->CR1; +} + +/*---------------Advanced TIMER functions -----------------------------------------*/ +/*********************************************************************//** + * @brief Timer wait (microseconds) + * @param[in] time number of microseconds waiting + * @return None + **********************************************************************/ +void TIM_Waitus(uint32_t time) +{ + TIM_MATCHCFG_Type MatchConfigStruct; + LPC_TIM0->IR = 0xFFFFFFFF; + + MatchConfigStruct.MatchChannel = 0; + MatchConfigStruct.IntOnMatch = ENABLE; + MatchConfigStruct.ResetOnMatch = ENABLE; + MatchConfigStruct.StopOnMatch = ENABLE; + MatchConfigStruct.ExtMatchOutputType = 0; + MatchConfigStruct.MatchValue = time; + + TIM_ConfigMatch(LPC_TIM0, &MatchConfigStruct); + TIM_Cmd(LPC_TIM0,ENABLE); + //wait until interrupt flag occur + while(!(LPC_TIM0->IR & 0x01)); + TIM_ResetCounter(LPC_TIM0); +} +/*********************************************************************//** + * @brief Timer wait (milliseconds) + * @param[in] time number of millisecond waiting + * @return None + **********************************************************************/ +void TIM_Waitms(uint32_t time) +{ + TIM_Waitus(time * 1000); +} +/** + * @} + */ +#endif /*_TIM*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_uart.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..bcd9ef51e085c8ea470ec246251971736f3c323d --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_uart.c @@ -0,0 +1,1778 @@ +/********************************************************************** +* $Id$ lpc_uart.c 2011-06-02 +*//** +* @file lpc_uart.c +* @brief Contains all functions support for UART firmware library +* on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup UART + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _UART + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_uart.h" +#include "lpc_clkpwr.h" + +/* Private Functions ---------------------------------------------------------- */ + +static Status uart_set_divisors(UART_ID_Type UartID, uint32_t baudrate); +static LPC_UART_TypeDef *uart_get_pointer(UART_ID_Type UartID); + + +/*********************************************************************//** + * @brief Determines best dividers to get a target clock rate + * @param[in] UARTx Pointer to selected UART peripheral, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] baudrate Desired UART baud rate. + * @return Error status, could be: + * - SUCCESS + * - ERROR + **********************************************************************/ +static Status uart_set_divisors(UART_ID_Type UartID, uint32_t baudrate) +{ + Status errorStatus = ERROR; + + uint32_t uClk; + uint32_t d, m, bestd, bestm, tmp; + uint64_t best_divisor, divisor; + uint32_t current_error, best_error; + uint32_t recalcbaud; + + /* get UART block clock */ + uClk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + + /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers + * The formula is : + * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL) + * It involves floating point calculations. That's the reason the formulae are adjusted with + * Multiply and divide method.*/ + + /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions: + * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */ + best_error = 0xFFFFFFFF; /* Worst case */ + bestd = 0; + bestm = 0; + best_divisor = 0; + + for (m = 1 ; m <= 15 ;m++) + { + for (d = 0 ; d < m ; d++) + { + divisor = ((uint64_t)uClk << 28)*m / (baudrate*(m+d)); + current_error = divisor & 0xFFFFFFFF; + + tmp = divisor>>32; + + /* Adjust error */ + if(current_error > ((uint32_t)1<<31)) + { + current_error = -current_error; + tmp++; + } + + /* Out of range */ + if(tmp < 1 || tmp > 65536) + continue; + + if( current_error < best_error) + { + best_error = current_error; + best_divisor = tmp; + bestd = d; + bestm = m; + + if(best_error == 0) + break; + } + } /* end of inner for loop */ + + if (best_error == 0) + break; + } /* end of outer for loop */ + + /* can not find best match */ + if(best_divisor == 0) + return ERROR; + + recalcbaud = (uClk >> 4) * bestm / (best_divisor * (bestm + bestd)); + + /* reuse best_error to evaluate baud error*/ + if(baudrate > recalcbaud) + best_error = baudrate - recalcbaud; + else + best_error = recalcbaud -baudrate; + + best_error = best_error * 100 / baudrate; + + if (best_error < UART_ACCEPTED_BAUDRATE_ERROR) + { + if (UartID == UART_1) + { + LPC_UART1->LCR |= UART_LCR_DLAB_EN; + + LPC_UART1->DLM = UART_LOAD_DLM(best_divisor); + + LPC_UART1->DLL = UART_LOAD_DLL(best_divisor); + + /* Then reset DLAB bit */ + LPC_UART1->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; + + LPC_UART1->FDR = (UART_FDR_MULVAL(bestm) + | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK; + } + else if (UartID == UART_4) + { + LPC_UART4->LCR |= UART_LCR_DLAB_EN; + + LPC_UART4->DLM = UART_LOAD_DLM(best_divisor); + + LPC_UART4->DLL = UART_LOAD_DLL(best_divisor); + + /* Then reset DLAB bit */ + LPC_UART4->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; + + LPC_UART4->FDR = (UART_FDR_MULVAL(bestm) + | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK; + } + + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + UARTx->LCR |= UART_LCR_DLAB_EN; + + UARTx->DLM = UART_LOAD_DLM(best_divisor); + + UARTx->DLL = UART_LOAD_DLL(best_divisor); + + /* Then reset DLAB bit */ + UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; + + UARTx->FDR = (UART_FDR_MULVAL(bestm) \ + | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK; + } + errorStatus = SUCCESS; + } + + return errorStatus; +} +/*********************************************************************//** + * @brief Get the pointer of a given Uart + * @param[in] UARTx Pointer to selected UART peripheral, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return LPC_UART0~LPC_UART4 + **********************************************************************/ +LPC_UART_TypeDef *uart_get_pointer(UART_ID_Type UartID) +{ + LPC_UART_TypeDef *UARTx = NULL; + switch(UartID) + { + case UART_0: + UARTx = LPC_UART0; + break; + case UART_2: + UARTx = LPC_UART2; + break; + case UART_3: + UARTx = LPC_UART3; + break; + default: + break; + } + return UARTx; +} + +/* End of Private Functions ---------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup UART_Public_Functions + * @{ + */ +/* UART Init/DeInit functions -------------------------------------------------*/ +/********************************************************************//** + * @brief Initializes the UARTx peripheral according to the specified + * parameters in the UART_ConfigStruct. + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] UART_ConfigStruct Pointer to a UART_CFG_Type structure +* that contains the configuration information for the +* specified UART peripheral. + * @return None + *********************************************************************/ +void UART_Init(UART_ID_Type UartID, UART_CFG_Type *UART_ConfigStruct) +{ + uint32_t tmp; + switch (UartID) + { + case UART_0: + case UART_2: + case UART_3: + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + if(UartID == UART_0) + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE); + else if(UartID == UART_2) + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE); + else if(UartID == UART_3) + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE);; + /* FIFOs are empty */ + UARTx->FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS); + + // Disable FIFO + UARTx->FCR = 0; + + // Dummy reading + while (UARTx->LSR & UART_LSR_RDR) + { + tmp = UARTx->RBR; + } + + UARTx->TER = UART_TER_TXEN; + + // Wait for current transmit complete + while (!(UARTx->LSR & UART_LSR_THRE)); + + // Disable Tx + UARTx->TER = 0; + + // Disable interrupt + UARTx->IER = 0; + + // Set LCR to default state + UARTx->LCR = 0; + + // Set ACR to default state + UARTx->ACR = 0; + + // Set RS485 control to default state + UARTx->RS485CTRL = 0; + + // Set RS485 delay timer to default state + UARTx->RS485DLY = 0; + + // Set RS485 addr match to default state + UARTx->ADRMATCH = 0; + + // Dummy reading + tmp = UARTx->LSR; + } + break; + case UART_1: + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE); + + /* FIFOs are empty */ + LPC_UART1->FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS); + + // Disable FIFO + LPC_UART1->FCR = 0; + + // Dummy reading + while (LPC_UART1->LSR & UART_LSR_RDR) + { + tmp = LPC_UART1->RBR; + } + + LPC_UART1->TER = UART_TER_TXEN; + + // Wait for current transmit complete + while (!(LPC_UART1->LSR & UART_LSR_THRE)); + + // Disable Tx + LPC_UART1->TER = 0; + + // Disable interrupt + LPC_UART1->IER = 0; + + // Set LCR to default state + LPC_UART1->LCR = 0; + + // Set ACR to default state + LPC_UART1->ACR = 0; + + // Set RS485 control to default state + LPC_UART1->RS485CTRL = 0; + + // Set RS485 delay timer to default state + LPC_UART1->RS485DLY = 0; + + // Set RS485 addr match to default state + LPC_UART1->ADRMATCH = 0; + + // Dummy reading + tmp = LPC_UART1->LSR; + + // Set Modem Control to default state + LPC_UART1->MCR = 0; + + //Dummy Reading to Clear Status + tmp = LPC_UART1->MSR; + } + break; + case UART_4: + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART4, ENABLE); + + /* FIFOs are empty */ + LPC_UART4->FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS); + + // Disable FIFO + LPC_UART4->FCR = 0; + + // Dummy reading + while (LPC_UART4->LSR & UART_LSR_RDR) + { + tmp = LPC_UART4->RBR; + } + + LPC_UART4->TER = UART4_TER_TXEN; + + // Wait for current transmit complete + while (!(LPC_UART4->LSR & UART_LSR_THRE)); + + // Disable Tx + LPC_UART4->TER = 0; + + // Disable interrupt + LPC_UART4->IER = 0; + + // Set LCR to default state + LPC_UART4->LCR = 0; + + // Set ACR to default state + LPC_UART4->ACR = 0; + + // Set RS485 control to default state + LPC_UART4->RS485CTRL = 0; + + // Set RS485 delay timer to default state + LPC_UART4->RS485DLY = 0; + + // Set RS485 addr match to default state + LPC_UART4->ADRMATCH = 0; + + // Dummy reading + tmp = LPC_UART4->LSR; + + // Set IrDA Mode to default state + LPC_UART4->ICR = 0; + } + break; + } + + // Set Line Control register ---------------------------- + + uart_set_divisors(UartID, (UART_ConfigStruct->Baud_rate)); + + if (UartID == UART_1) + { + tmp = (LPC_UART1->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \ + & UART_LCR_BITMASK; + } + else if (UartID == UART_4) + { + tmp = (LPC_UART4->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \ + & UART_LCR_BITMASK; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK; + } + + switch (UART_ConfigStruct->Databits) + { + case UART_DATABIT_5: + tmp |= UART_LCR_WLEN5; + break; + + case UART_DATABIT_6: + tmp |= UART_LCR_WLEN6; + break; + + case UART_DATABIT_7: + tmp |= UART_LCR_WLEN7; + break; + + case UART_DATABIT_8: + + default: + tmp |= UART_LCR_WLEN8; + break; + } + + if (UART_ConfigStruct->Parity == UART_PARITY_NONE) + { + // Do nothing... + } + else + { + tmp |= UART_LCR_PARITY_EN; + switch (UART_ConfigStruct->Parity) + { + case UART_PARITY_ODD: + tmp |= UART_LCR_PARITY_ODD; + break; + + case UART_PARITY_EVEN: + tmp |= UART_LCR_PARITY_EVEN; + break; + + case UART_PARITY_SP_1: + tmp |= UART_LCR_PARITY_F_1; + break; + + case UART_PARITY_SP_0: + tmp |= UART_LCR_PARITY_F_0; + break; + + default: + break; + } + } + + switch (UART_ConfigStruct->Stopbits) + { + case UART_STOPBIT_2: + tmp |= UART_LCR_STOPBIT_SEL; + break; + + case UART_STOPBIT_1: + + default: + // Do no thing + break; + } + + + // Write back to LCR, configure FIFO and Disable Tx + if (UartID == UART_1) + { + LPC_UART1->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); + } + else if (UartID == UART_4) + { + LPC_UART4->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); + } +} + +/*********************************************************************//** + * @brief De-initializes the UARTx peripheral registers to their + * default reset values. + * @param[in] UartID UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return None + **********************************************************************/ +void UART_DeInit(UART_ID_Type UartID) +{ + UART_TxCmd(UartID, DISABLE); + if (UartID == UART_0) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE); + } + + else if (UartID == UART_1) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE); + } + + else if (UartID == UART_2) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE); + } + + else if (UartID == UART_3) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE); + } + else if (UartID == UART_4) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART4, DISABLE); + } +} + +/*****************************************************************************//** +* @brief Fills each UART_InitStruct member with its default value: +* - 115200 bps +* - 8-bit data +* - 1 Stopbit +* - None Parity +* @param[in] UART_InitStruct Pointer to a UART_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct) +{ + UART_InitStruct->Baud_rate = 115200; + + UART_InitStruct->Databits = UART_DATABIT_8; + + UART_InitStruct->Parity = UART_PARITY_NONE; + + UART_InitStruct->Stopbits = UART_STOPBIT_1; +} + +/* UART Send/Recieve functions -------------------------------------------------*/ +/*********************************************************************//** + * @brief Transmit a single data through UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] Data Data to transmit (must be 8-bit long) + * @return None + **********************************************************************/ +void UART_SendByte(UART_ID_Type UartID, uint8_t Data) +{ + switch (UartID) + { + case UART_0: + LPC_UART0->THR = Data & UART_THR_MASKBIT; + break; + case UART_1: + LPC_UART1->THR = Data & UART_THR_MASKBIT; + break; + case UART_2: + LPC_UART2->THR = Data & UART_THR_MASKBIT; + break; + case UART_3: + LPC_UART3->THR = Data & UART_THR_MASKBIT; + break; + case UART_4: + LPC_UART4->THR = Data & UART_THR_MASKBIT; + break; + } + +} + + +/*********************************************************************//** + * @brief Receive a single data from UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return Data received + **********************************************************************/ +uint8_t UART_ReceiveByte(UART_ID_Type UartID) +{ + switch (UartID) + { + case UART_0: + return (LPC_UART0->RBR & UART_RBR_MASKBIT); + case UART_1: + return (LPC_UART1->RBR & UART_RBR_MASKBIT); + case UART_2: + return (LPC_UART2->RBR & UART_RBR_MASKBIT); + case UART_3: + return (LPC_UART3->RBR & UART_RBR_MASKBIT); + case UART_4: + return (LPC_UART4->RBR & UART_RBR_MASKBIT); + } + return 0x00; +} + +/*********************************************************************//** + * @brief Send a block of data via UART peripheral + * @param[in] UARTx Selected UART peripheral used to send data, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] txbuf Pointer to Transmit buffer + * @param[in] buflen Length of Transmit buffer + * @param[in] flag Flag used in UART transfer, should be + * NONE_BLOCKING or BLOCKING + * @return Number of bytes sent. + * + * Note: when using UART in BLOCKING mode, a time-out condition is used + * via defined symbol UART_BLOCKING_TIMEOUT. + **********************************************************************/ +uint32_t UART_Send(UART_ID_Type UartID, uint8_t *txbuf, + uint32_t buflen, TRANSFER_BLOCK_Type flag) +{ + uint32_t bToSend, bSent, timeOut, fifo_cnt; + uint8_t *pChar = txbuf; + __IO uint32_t *LSR = NULL; + + switch (UartID) + { + case UART_0: + LSR = (__IO uint32_t *)&LPC_UART0->LSR; + break; + case UART_1: + LSR = (__IO uint32_t *)&LPC_UART1->LSR; + break; + case UART_2: + LSR = (__IO uint32_t *)&LPC_UART2->LSR; + break; + case UART_3: + LSR = (__IO uint32_t *)&LPC_UART3->LSR; + break; + case UART_4: + LSR = (__IO uint32_t *)&LPC_UART4->LSR; + break; + } + + bToSend = buflen; + + // blocking mode + if (flag == BLOCKING) + { + bSent = 0; + while (bToSend) + { + timeOut = UART_BLOCKING_TIMEOUT; + + // Wait for THR empty with timeout + while (!(*LSR & UART_LSR_THRE)) + { + if (timeOut == 0) + break; + + timeOut--; + } + + // Time out! + if(timeOut == 0) + break; + + fifo_cnt = UART_TX_FIFO_SIZE; + + while (fifo_cnt && bToSend) + { + UART_SendByte(UartID, (*pChar++)); + + fifo_cnt--; + + bToSend--; + + bSent++; + } + } + } + + // None blocking mode + else + { + bSent = 0; + while (bToSend) + { + if (bToSend == 0) + break; + + if (!(*LSR & UART_LSR_THRE)) + { + break; + } + + fifo_cnt = UART_TX_FIFO_SIZE; + + while (fifo_cnt && bToSend) + { + UART_SendByte(UartID, (*pChar++)); + + bToSend--; + + fifo_cnt--; + + bSent++; + } + } + } + + return bSent; +} + +/*********************************************************************//** + * @brief Receive a block of data via UART peripheral + * @param[in] UARTx Selected UART peripheral used to send data, + * should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[out] rxbuf Pointer to Received buffer + * @param[in] buflen Length of Received buffer + * @param[in] flag Flag mode, should be NONE_BLOCKING or BLOCKING + + * @return Number of bytes received + * + * Note: when using UART in BLOCKING mode, a time-out condition is used + * via defined symbol UART_BLOCKING_TIMEOUT. + **********************************************************************/ +uint32_t UART_Receive(UART_ID_Type UartID, uint8_t *rxbuf, + uint32_t buflen, TRANSFER_BLOCK_Type flag) +{ + uint32_t bToRecv, bRecv, timeOut; + uint8_t *pChar = rxbuf; + __IO uint32_t *LSR = NULL; + + switch (UartID) + { + case UART_0: + LSR = (__IO uint32_t *)&LPC_UART0->LSR; + break; + case UART_1: + LSR = (__IO uint32_t *)&LPC_UART1->LSR; + break; + case UART_2: + LSR = (__IO uint32_t *)&LPC_UART2->LSR; + break; + case UART_3: + LSR = (__IO uint32_t *)&LPC_UART3->LSR; + break; + case UART_4: + LSR = (__IO uint32_t *)&LPC_UART4->LSR; + break; + } + + bToRecv = buflen; + + // Blocking mode + if (flag == BLOCKING) + { + bRecv = 0; + while (bToRecv) + { + timeOut = UART_BLOCKING_TIMEOUT; + while (!(*LSR & UART_LSR_RDR)) + { + if (timeOut == 0) + break; + + timeOut--; + } + + // Time out! + if(timeOut == 0) + break; + + // Get data from the buffer + (*pChar++) = UART_ReceiveByte(UartID); + + bToRecv--; + + bRecv++; + } + } + // None blocking mode + else + { + bRecv = 0; + while (bToRecv) + { + if (!(*LSR & UART_LSR_RDR)) + { + break; + } + else + { + (*pChar++) = UART_ReceiveByte(UartID); + + bRecv++; + + bToRecv--; + } + } + } + + return bRecv; +} + +/*********************************************************************//** + * @brief Force BREAK character on UART line, output pin UARTx TXD is + forced to logic 0. + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return None + **********************************************************************/ +void UART_ForceBreak(UART_ID_Type UartID) +{ + switch (UartID) + { + case UART_0: + LPC_UART0->LCR |= UART_LCR_BREAK_EN; + break; + case UART_1: + LPC_UART1->LCR |= UART_LCR_BREAK_EN; + break; + case UART_2: + LPC_UART2->LCR |= UART_LCR_BREAK_EN; + break; + case UART_3: + LPC_UART3->LCR |= UART_LCR_BREAK_EN; + break; + case UART_4: + LPC_UART4->LCR |= UART_LCR_BREAK_EN; + break; + } +} + + +/********************************************************************//** + * @brief Enable or disable specified UART interrupt. + * @param[in] UARTx UART peripheral selected, should be + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] UARTIntCfg Specifies the interrupt flag, + * should be one of the following: + - UART_INTCFG_RBR : RBR Interrupt enable + - UART_INTCFG_THRE : THR Interrupt enable + - UART_INTCFG_RLS : RX line status interrupt enable + - UART1_INTCFG_MS : Modem status interrupt enable (UART1 only) + - UART1_INTCFG_CTS : CTS1 signal transition interrupt enable (UART1 only) + - UART_INTCFG_ABEO : Enables the end of auto-baud interrupt + - UART_INTCFG_ABTO : Enables the auto-baud time-out interrupt + * @param[in] NewState New state of specified UART interrupt type, + * should be: + * - ENALBE: Enable this UART interrupt type. +* - DISALBE: Disable this UART interrupt type. + * @return None + *********************************************************************/ +void UART_IntConfig(UART_ID_Type UartID, UART_INT_Type UARTIntCfg, FunctionalState NewState) +{ + uint32_t tmp; + __IO uint32_t *IER = NULL; + uint32_t IERMask = 0; + + switch (UartID) + { + case UART_0: + IER = &LPC_UART0->IER; + IERMask = UART_IER_BITMASK; + break; + case UART_1: + IER = &LPC_UART1->IER; + IERMask = UART1_IER_BITMASK; + break; + case UART_2: + IER = &LPC_UART2->IER; + IERMask = UART_IER_BITMASK; + break; + case UART_3: + IER = &LPC_UART3->IER; + IERMask = UART_IER_BITMASK; + break; + case UART_4: + IER = &LPC_UART4->IER; + IERMask = UART_IER_BITMASK; + break; + } + + + switch(UARTIntCfg) + { + case UART_INTCFG_RBR: + tmp = UART_IER_RBRINT_EN; + break; + + case UART_INTCFG_THRE: + tmp = UART_IER_THREINT_EN; + break; + + case UART_INTCFG_RLS: + tmp = UART_IER_RLSINT_EN; + break; + + case UART_INTCFG_MS: + tmp = UART1_IER_MSINT_EN; + break; + + case UART_INTCFG_CTS: + tmp = UART1_IER_CTSINT_EN; + break; + + case UART_INTCFG_ABEO: + tmp = UART_IER_ABEOINT_EN; + break; + + case UART_INTCFG_ABTO: + tmp = UART_IER_ABTOINT_EN; + break; + } + + if (NewState == ENABLE) + { + *IER |= tmp& IERMask; + } + else + { + *IER &= (~tmp) & IERMask; + } +} + + +/********************************************************************//** + * @brief Get current value of Line Status register in UART peripheral. + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return Current value of Line Status register in UART peripheral. + * Note: The return value of this function must be ANDed with each member in + * UART_LS_Type enumeration to determine current flag status + * corresponding to each Line status type. Because some flags in + * Line Status register will be cleared after reading, the next reading + * Line Status register could not be correct. So this function used to + * read Line status register in one time only, then the return value + * used to check all flags. + *********************************************************************/ +uint8_t UART_GetLineStatus(UART_ID_Type UartID) +{ + switch (UartID) + { + case UART_0: + return ((LPC_UART0->LSR) & UART_LSR_BITMASK); + case UART_1: + return ((LPC_UART1->LSR) & UART_LSR_BITMASK); + case UART_2: + return ((LPC_UART2->LSR) & UART_LSR_BITMASK); + case UART_3: + return ((LPC_UART3->LSR) & UART_LSR_BITMASK); + case UART_4: + return ((LPC_UART4->LSR) & UART_LSR_BITMASK); + } + return 0; +} + +/********************************************************************//** + * @brief Get Interrupt Identification value + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return Current value of UART UIIR register in UART peripheral. + *********************************************************************/ +uint32_t UART_GetIntId(UART_ID_Type UartID) +{ + switch (UartID) + { + case UART_0: + return ((LPC_UART0->IIR) & UART_IIR_BITMASK); + case UART_1: + return ((LPC_UART1->IIR) & UART_IIR_BITMASK); + case UART_2: + return ((LPC_UART2->IIR) & UART_IIR_BITMASK); + case UART_3: + return ((LPC_UART3->IIR) & UART_IIR_BITMASK); + case UART_4: + return ((LPC_UART4->IIR) & UART_IIR_BITMASK); + } + return 0; +} + +/*********************************************************************//** + * @brief Check whether if UART is busy or not + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @return RESET if UART is not busy, otherwise return SET. + **********************************************************************/ +FlagStatus UART_CheckBusy(UART_ID_Type UartID) +{ + uint32_t LSR = 0; + switch (UartID) + { + case UART_0: + LSR = (LPC_UART0)->LSR & UART_LSR_TEMT; + break; + case UART_1: + LSR = (LPC_UART1)->LSR & UART_LSR_TEMT; + break; + case UART_2: + LSR = (LPC_UART2)->LSR & UART_LSR_TEMT; + break; + case UART_3: + LSR = (LPC_UART3)->LSR & UART_LSR_TEMT; + break; + case UART_4: + LSR = (LPC_UART4)->LSR & UART_LSR_TEMT; + break; + } + + if (LSR & UART_LSR_TEMT) + { + return RESET; + } + return SET; +} + + +/*********************************************************************//** + * @brief Configure FIFO function on selected UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] FIFOCfg Pointer to a UART_FIFO_CFG_Type Structure that + * contains specified information about FIFO configuration + * @return none + **********************************************************************/ +void UART_FIFOConfig(UART_ID_Type UartID, UART_FIFO_CFG_Type *FIFOCfg) +{ + uint8_t tmp = 0; + + tmp |= UART_FCR_FIFO_EN; + + switch (FIFOCfg->FIFO_Level) + { + case UART_FIFO_TRGLEV0: + tmp |= UART_FCR_TRG_LEV0; + break; + + case UART_FIFO_TRGLEV1: + tmp |= UART_FCR_TRG_LEV1; + break; + + case UART_FIFO_TRGLEV2: + tmp |= UART_FCR_TRG_LEV2; + break; + + case UART_FIFO_TRGLEV3: + + default: + tmp |= UART_FCR_TRG_LEV3; + break; + } + + if (FIFOCfg->FIFO_ResetTxBuf == ENABLE) + { + tmp |= UART_FCR_TX_RS; + } + + if (FIFOCfg->FIFO_ResetRxBuf == ENABLE) + { + tmp |= UART_FCR_RX_RS; + } + + if (FIFOCfg->FIFO_DMAMode == ENABLE) + { + tmp |= UART_FCR_DMAMODE_SEL; + } + + + //write to FIFO control register + switch (UartID) + { + case UART_0: + LPC_UART0->FCR = tmp & UART_FCR_BITMASK; + break; + case UART_1: + LPC_UART1->FCR = tmp & UART_FCR_BITMASK; + break; + case UART_2: + LPC_UART2->FCR = tmp & UART_FCR_BITMASK; + break; + case UART_3: + LPC_UART3->FCR = tmp & UART_FCR_BITMASK; + break; + case UART_4: + LPC_UART4->FCR = tmp & UART_FCR_BITMASK; + break; + } +} + +/*****************************************************************************//** +* @brief Fills each UART_FIFOInitStruct member with its default value: +* - FIFO_DMAMode = DISABLE +* - FIFO_Level = UART_FIFO_TRGLEV0 +* - FIFO_ResetRxBuf = ENABLE +* - FIFO_ResetTxBuf = ENABLE +* - FIFO_State = ENABLE +* @param[in] UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct) +{ + UART_FIFOInitStruct->FIFO_DMAMode = DISABLE; + + UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0; + + UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE; + + UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE; +} + + +/*********************************************************************//** + * @brief Start/Stop Auto Baudrate activity + * @param[in] UARTx UART peripheral selected, should be + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] ABConfigStruct A pointer to UART_AB_CFG_Type structure that + * contains specified information about UART + * auto baudrate configuration + * @param[in] NewState New State of Auto baudrate activity, should be: + * - ENABLE: Start this activity + * - DISABLE: Stop this activity + * Note: Auto-baudrate mode enable bit will be cleared once this mode + * completed. + * @return none + **********************************************************************/ +void UART_ABCmd(UART_ID_Type UartID, UART_AB_CFG_Type *ABConfigStruct, + FunctionalState NewState) +{ + uint32_t tmp; + + tmp = 0; + if (NewState == ENABLE) + { + if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1) + { + tmp |= UART_ACR_MODE; + } + if (ABConfigStruct->AutoRestart == ENABLE) + { + tmp |= UART_ACR_AUTO_RESTART; + } + } + + if (UartID == UART_1) + { + if (NewState == ENABLE) + { + // Clear DLL and DLM value + LPC_UART1->LCR |= UART_LCR_DLAB_EN; + + LPC_UART1->DLL = 0; + + LPC_UART1->DLM = 0; + + LPC_UART1->LCR &= ~UART_LCR_DLAB_EN; + + // FDR value must be reset to default value + LPC_UART1->FDR = 0x10; + + LPC_UART1->ACR = UART_ACR_START | tmp; + } + else + { + LPC_UART1->ACR = 0; + } + } + else if (UartID == UART_4) + { + if (NewState == ENABLE) + { + // Clear DLL and DLM value + LPC_UART4->LCR |= UART_LCR_DLAB_EN; + + LPC_UART4->DLL = 0; + + LPC_UART4->DLM = 0; + + LPC_UART4->LCR &= ~UART_LCR_DLAB_EN; + + // FDR value must be reset to default value + LPC_UART4->FDR = 0x10; + + LPC_UART4->ACR = UART_ACR_START | tmp; + } + else + { + LPC_UART4->ACR = 0; + } + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + if (NewState == ENABLE) + { + // Clear DLL and DLM value + UARTx->LCR |= UART_LCR_DLAB_EN; + + UARTx->DLL = 0; + + UARTx->DLM = 0; + + UARTx->LCR &= ~UART_LCR_DLAB_EN; + + // FDR value must be reset to default value + UARTx->FDR = 0x10; + + UARTx->ACR = UART_ACR_START | tmp; + } + else + { + UARTx->ACR = 0; + } + } +} + +/*********************************************************************//** + * @brief Clear Autobaud Interrupt Pending + * @param[in] UARTx UART peripheral selected, should be + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] ABIntType type of auto-baud interrupt, should be: + * - UART_AUTOBAUD_INTSTAT_ABEO: End of Auto-baud interrupt + * - UART_AUTOBAUD_INTSTAT_ABTO: Auto-baud time out interrupt + * @return none + **********************************************************************/ +void UART_ABClearIntPending(UART_ID_Type UartID, UART_ABEO_Type ABIntType) +{ + if (UartID == UART_1) + { + LPC_UART1->ACR |= ABIntType; + } + else if (UartID == UART_4) + { + LPC_UART4->ACR |= ABIntType; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + UARTx->ACR |= ABIntType; + } +} + +/*********************************************************************//** + * @brief Enable/Disable transmission on UART TxD pin + * @param[in] UARTx UART peripheral selected, should be: + * - UART_0: UART0 peripheral + * - UART_1: UART1 peripheral + * - UART_2: UART2 peripheral + * - UART_3: UART3 peripheral + * - UART_4: UART4 peripheral + * @param[in] NewState New State of Tx transmission function, should be: + * - ENABLE: Enable this function + - DISABLE: Disable this function + * @return none + **********************************************************************/ +void UART_TxCmd(UART_ID_Type UartID, FunctionalState NewState) +{ + if (NewState == ENABLE) + { + if (UartID == UART_1) + { + LPC_UART1->TER |= UART_TER_TXEN; + } + else if (UartID == UART_4) + { + LPC_UART4->TER |= UART4_TER_TXEN; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + UARTx->TER |= UART_TER_TXEN; + } + } + else + { + if (UartID == UART_1) + { + LPC_UART1->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; + } + else if (UartID == UART_4) + { + LPC_UART4->TER &= (~UART4_TER_TXEN) & UART4_TER_BITMASK; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; + } + } +} + +/* UART IrDA functions ---------------------------------------------------*/ +/*********************************************************************//** + * @brief Enable or disable inverting serial input function of IrDA + * on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART4 (only) + * @param[in] NewState New state of inverting serial input, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return none + **********************************************************************/ +void UART_IrDAInvtInputCmd(UART_ID_Type UartID, FunctionalState NewState) +{ + if (UartID != UART_4) + return; + + if (NewState == ENABLE) + { + LPC_UART4->ICR |= UART_ICR_IRDAINV; + } + else if (NewState == DISABLE) + { + LPC_UART4->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK; + } + +} + + +/*********************************************************************//** + * @brief Enable or disable IrDA function on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART4 (only) + * @param[in] NewState New state of IrDA function, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return none + **********************************************************************/ +void UART_IrDACmd(UART_ID_Type UartID, FunctionalState NewState) +{ + if (UartID != UART_4) + return; + + if (NewState == ENABLE) + { + LPC_UART4->ICR |= UART_ICR_IRDAEN; + } + else + { + LPC_UART4->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Configure Pulse divider for IrDA function on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART4 (only) + * @param[in] PulseDiv Pulse Divider value from Peripheral clock, + * should be one of the following: + - UART_IrDA_PULSEDIV2 : Pulse width = 2 * Tpclk + - UART_IrDA_PULSEDIV4 : Pulse width = 4 * Tpclk + - UART_IrDA_PULSEDIV8 : Pulse width = 8 * Tpclk + - UART_IrDA_PULSEDIV16 : Pulse width = 16 * Tpclk + - UART_IrDA_PULSEDIV32 : Pulse width = 32 * Tpclk + - UART_IrDA_PULSEDIV64 : Pulse width = 64 * Tpclk + - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk + - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk + + * @return none + **********************************************************************/ +void UART_IrDAPulseDivConfig(UART_ID_Type UartID, UART_IrDA_PULSE_Type PulseDiv) +{ + uint32_t tmp, tmp1; + + if (UartID != UART_4) + return; + + tmp1 = UART_ICR_PULSEDIV(PulseDiv); + + tmp = LPC_UART4->ICR & (~ UART_ICR_PULSEDIV(7)); + + tmp |= tmp1 | UART_ICR_FIXPULSE_EN; + + LPC_UART4->ICR = tmp & UART_ICR_BITMASK; +} + +/* UART1 FullModem function ---------------------------------------------*/ + +/*********************************************************************//** + * @brief Force pin DTR/RTS corresponding to given state (Full modem mode) + * @param[in] UARTx LPC_UART1 (only) + * @param[in] Pin Pin that NewState will be applied to, should be: + * - UART1_MODEM_PIN_DTR: DTR pin. + * - UART1_MODEM_PIN_RTS: RTS pin. + * @param[in] NewState New State of DTR/RTS pin, should be: + * - INACTIVE: Force the pin to inactive signal. + - ACTIVE: Force the pin to active signal. + * @return none + **********************************************************************/ +void UART_FullModemForcePinState(UART_ID_Type UartID, + UART_MODEM_PIN_Type Pin, + UART1_SignalState NewState) +{ + uint8_t tmp = 0; + if (UartID != UART_1) + return; + switch (Pin) + { + case UART1_MODEM_PIN_DTR: + tmp = UART1_MCR_DTR_CTRL; + break; + + case UART1_MODEM_PIN_RTS: + tmp = UART1_MCR_RTS_CTRL; + break; + + default: + break; + } + + if (NewState == ACTIVE) + { + LPC_UART1->MCR |= tmp; + } + else + { + LPC_UART1->MCR &= (~tmp) & UART1_MCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Configure Full Modem mode for UART peripheral + * @param[in] UARTx LPC_UART1 (only) + * @param[in] Mode Full Modem mode, should be: + * - UART1_MODEM_MODE_LOOPBACK: Loop back mode. + * - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode. + * - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode. + * @param[in] NewState New State of this mode, should be: + * - ENABLE: Enable this mode. + - DISABLE: Disable this mode. + * @return none + **********************************************************************/ +void UART_FullModemConfigMode(UART_ID_Type UartID, UART_MODEM_MODE_Type Mode, + FunctionalState NewState) +{ + uint8_t tmp; + + if(UartID != UART_1) + return; + + switch(Mode) + { + case UART1_MODEM_MODE_LOOPBACK: + tmp = UART1_MCR_LOOPB_EN; + break; + + case UART1_MODEM_MODE_AUTO_RTS: + tmp = UART1_MCR_AUTO_RTS_EN; + break; + + case UART1_MODEM_MODE_AUTO_CTS: + tmp = UART1_MCR_AUTO_CTS_EN; + break; + + default: + break; + } + + if (NewState == ENABLE) + { + LPC_UART1->MCR |= tmp; + } + else + { + LPC_UART1->MCR &= (~tmp) & UART1_MCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Get current status of modem status register + * @param[in] UARTx LPC_UART1 (only) + * @return Current value of modem status register + * Note: The return value of this function must be ANDed with each member + * UART_MODEM_STAT_type enumeration to determine current flag status + * corresponding to each modem flag status. Because some flags in + * modem status register will be cleared after reading, the next reading + * modem register could not be correct. So this function used to + * read modem status register in one time only, then the return value + * used to check all flags. + **********************************************************************/ +uint8_t UART_FullModemGetStatus(UART_ID_Type UartID) +{ + if(UartID != UART_1) + return 0; + + return ((LPC_UART1->MSR) & UART1_MSR_BITMASK); +} + + +/* UART RS485 functions --------------------------------------------------------------*/ +/*********************************************************************//** + * @brief Configure UART peripheral in RS485 mode according to the specified +* parameters in the RS485ConfigStruct. + * @param[in] UARTx LPC_UART0 ~LPC_UART4 + * @param[in] RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure +* that contains the configuration information for specified UART +* in RS485 mode. + * @return None + **********************************************************************/ +void UART_RS485Config(UART_ID_Type UartID, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct) +{ + uint32_t tmp; + __IO uint32_t *RS485DLY, *ADRMATCH, *RS485CTRL, *LCR; + + tmp = 0; + if (UartID == UART_1) + { + RS485DLY = (__IO uint32_t *)&LPC_UART1->RS485DLY; + ADRMATCH = (__IO uint32_t *)&LPC_UART1->ADRMATCH; + LCR = (__IO uint32_t *)&LPC_UART1->LCR; + RS485CTRL = (__IO uint32_t *)&LPC_UART1->RS485CTRL; + } + else if (UartID == UART_4) + { + RS485DLY = (__IO uint32_t *)&LPC_UART4->RS485DLY; + ADRMATCH = (__IO uint32_t *)&LPC_UART4->ADRMATCH; + LCR = (__IO uint32_t *)&LPC_UART4->LCR; + RS485CTRL = (__IO uint32_t *)&LPC_UART4->RS485CTRL; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + RS485DLY = (__IO uint32_t *)&UARTx->RS485DLY; + ADRMATCH = (__IO uint32_t *)&UARTx->ADRMATCH; + LCR = (__IO uint32_t *)&UARTx->LCR; + RS485CTRL = (__IO uint32_t *)&UARTx->RS485CTRL; + } + // If Auto Direction Control is enabled - This function is used in Master mode + if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE) + { + tmp |= UART_RS485CTRL_DCTRL_EN; + + // Set polar + if (RS485ConfigStruct->DirCtrlPol_Level == SET) + { + tmp |= UART_RS485CTRL_OINV_1; + } + + // Set pin according to. This condition is only with UART1. The others are used + // OE pin as default for control the direction of RS485 buffer IC + if ((RS485ConfigStruct->DirCtrlPin == UART_RS485_DIRCTRL_DTR) && + (UartID == UART_1)) + { + tmp |= UART_RS485CTRL_SEL_DTR; + } + + // Fill delay time + *RS485DLY = RS485ConfigStruct->DelayValue & UART_RS485DLY_BITMASK; + } + + // MultiDrop mode is enable + if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE) + { + tmp |= UART_RS485CTRL_NMM_EN; + } + + // Auto Address Detect function + if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE) + { + tmp |= UART_RS485CTRL_AADEN; + + // Fill Match Address + *ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART_RS485ADRMATCH_BITMASK; + } + + // Receiver is disable + if (RS485ConfigStruct->Rx_State == DISABLE) + { + tmp |= UART_RS485CTRL_RX_DIS; + } + + // write back to RS485 control register + *RS485CTRL = tmp & UART_RS485CTRL_BITMASK; + + // Enable Parity function and leave parity in stick '0' parity as default + *LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN); +} + +/*********************************************************************//** + * @brief Enable/Disable receiver in RS485 module in UART1 + * @param[in] UARTx LPC_UART1 (only) + * @param[in] NewState New State of command, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return None + **********************************************************************/ +void UART_RS485ReceiverCmd(UART_ID_Type UartID, FunctionalState NewState) +{ + __IO uint32_t *RS485CTRL; + if (UartID == UART_1) + { + RS485CTRL = (__IO uint32_t *)&LPC_UART1->RS485DLY; + } + else if (UartID == UART_4) + { + RS485CTRL = (__IO uint32_t *)&LPC_UART4->RS485DLY; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + RS485CTRL = (__IO uint32_t *)&UARTx->RS485DLY; + } + if (NewState == ENABLE) + { + *RS485CTRL &= ~UART_RS485CTRL_RX_DIS; + } + else + { + *RS485CTRL |= UART_RS485CTRL_RX_DIS; + } +} + +/*********************************************************************//** + * @brief Send data on RS485 bus with specified parity stick value (9-bit mode). + * @param[in] UARTx LPC_UART1 (only) + * @param[in] pDatFrm Pointer to data frame. + * @param[in] size Size of data. + * @param[in] ParityStick Parity Stick value, should be 0 or 1. + * @return None + **********************************************************************/ +uint32_t UART_RS485Send(UART_ID_Type UartID, uint8_t *pDatFrm, + uint32_t size, uint8_t ParityStick) +{ + uint8_t tmp, save; + uint32_t cnt; + __IO uint32_t *LCR, *LSR; + if (UartID == UART_1) + { + LCR = (__IO uint32_t *)&LPC_UART1->LCR; + LSR = (__IO uint32_t *)&LPC_UART1->LSR; + } + else if (UartID == UART_4) + { + LCR = (__IO uint32_t *)&LPC_UART4->LCR; + LSR = (__IO uint32_t *)&LPC_UART4->LSR; + } + else + { + LPC_UART_TypeDef *UARTx = uart_get_pointer(UartID); + LCR = (__IO uint32_t *)&UARTx->LCR; + LSR = (__IO uint32_t *)&UARTx->LSR; + } + + if (ParityStick) + { + save = tmp = *LCR & UART_LCR_BITMASK; + + tmp &= ~(UART_LCR_PARITY_EVEN); + + *LCR = tmp; + + cnt = UART_Send(UartID, pDatFrm, size, BLOCKING); + + while (!(*LSR & UART_LSR_TEMT)); + + *LCR = save; + } + else + { + cnt = UART_Send(UartID, pDatFrm, size, BLOCKING); + + while (!(*LSR & UART_LSR_TEMT)); + } + + return cnt; +} + +/*********************************************************************//** + * @brief Send Slave address frames on RS485 bus. + * @param[in] UARTx LPC_UART1 (only) + * @param[in] SlvAddr Slave Address. + * @return None + **********************************************************************/ +void UART_RS485SendSlvAddr(UART_ID_Type UartID, uint8_t SlvAddr) +{ + UART_RS485Send(UartID, &SlvAddr, 1, 1); +} + +/*********************************************************************//** + * @brief Send Data frames on RS485 bus. + * @param[in] UARTx LPC_UART1 (only) + * @param[in] pData Pointer to data to be sent. + * @param[in] size Size of data frame to be sent. + * @return None + **********************************************************************/ +uint32_t UART_RS485SendData(UART_ID_Type UartID, uint8_t *pData, uint32_t size) +{ + return (UART_RS485Send(UartID, pData, size, 0)); +} + +/** + * @} + */ +#endif /*_UART*/ +/** + * @} + */ +/* --------------------------------- End Of File ------------------------------ */ + diff --git a/bsp/lpc408x/Libraries/Drivers/source/lpc_wwdt.c b/bsp/lpc408x/Libraries/Drivers/source/lpc_wwdt.c new file mode 100644 index 0000000000000000000000000000000000000000..b4ca9465fca4e2b77bb73643b06c1cd24854a240 --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/lpc_wwdt.c @@ -0,0 +1,484 @@ +/********************************************************************** +* $Id$ lpc_wwdt.c 2011-06-02 +*//** +* @file lpc_wwdt.c +* @brief Contains all functions support for Wachtdog Timer +* firmware library on LPC +* @version 1.0 +* @date 02. June. 2011 +* @author NXP MCU SW Application Team +* +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +*********************************************************************** +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright 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. +**********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup WWDT + * @{ + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc_libcfg.h" +#else +#include "lpc_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ +#ifdef _WDT + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_wwdt.h" +#include "lpc_clkpwr.h" +#include "lpc_pinsel.h" + + + /* Public Functions ----------------------------------------------------------- */ + /** @addtogroup WDT_Public_Functions + * @{ + */ + + /********************************************************************//** + * @brief Set timeout value to Timer Constant register + * (if enable) to generate a WatchDog event if match + * + * @param[in] timeoutVal The value (counter) will write directly to + * Register w/o pre-calc + * + * @return None + *********************************************************************/ +int8_t WWDT_SetTimeOutRaw(uint32_t timeoutVal) +{ + int8_t retval = 0; + + if(timeoutVal < WWDT_TIMEOUT_MIN) + { + timeoutVal = WWDT_TIMEOUT_MIN; + retval = WWDT_FUNC_BAD_PARAM; + } + else if (timeoutVal > WWDT_TIMEOUT_MAX) + { + timeoutVal = WWDT_TIMEOUT_MAX; + retval = WWDT_FUNC_BAD_PARAM; + } + + LPC_WDT->TC = timeoutVal; + + return retval; +} + + +/********************************************************************//** + * @brief Set WDT timeout (cal by usec) to TC register + * + * @param[in] timeout The time (usec) to generate watchdog event if + * the watchdog counter reach this value + * + * @return WWDT_FUNC_OK if success + *********************************************************************/ +int8_t WWDT_SetTimeOut(uint32_t timeout) +{ + return WWDT_SetTimeOutRaw(WDT_GET_FROM_USEC(timeout)); +} + + +/*********************************************************************//** +* @brief Initial for Watchdog function by setting timeout +* +* @param[in] TimeOut time out value, should be in range: +* 2048 .. 134217728 +* +* @return WWDT_FUNC_OK if success + **********************************************************************/ +int8_t WWDT_Init(uint32_t TimeOut) +{ + return WWDT_SetTimeOut(TimeOut); +} + +/*********************************************************************//** + * @brief Configure the WatchDog by initialization all the timing + * value for register (Warning value, Window value,...) + * + * @param wdtCfg a the st_Wdt_Config type value + * + * @return None + **********************************************************************/ +void WWDT_Configure(st_Wdt_Config wdtCfg) +{ + WWDT_SetTimeOut(wdtCfg.wdtTmrConst); + + if(wdtCfg.wdtEnable) + { + LPC_WDT->MOD |= WWDT_WDMOD_WDEN; + } + else + { + LPC_WDT->MOD &= ~WWDT_WDMOD_WDEN; + } + + if(wdtCfg.wdtReset) + { + LPC_WDT->MOD |= WWDT_WDMOD_WDRESET; + } + else + { + LPC_WDT->MOD &= ~WWDT_WDMOD_WDRESET; + } + + if(wdtCfg.wdtProtect) + { + LPC_WDT->MOD |= WWDT_WDMOD_WDPROTECT; + } + else + { + LPC_WDT->MOD &= ~WWDT_WDMOD_WDPROTECT; + } + + WWDT_SetWarning(wdtCfg.wdtWarningVal); + + WWDT_SetWindow(wdtCfg.wdtWindowVal); +} + +/*********************************************************************//** + * @brief Start WatchDog with specific Timeout + * + * @param TimeOut specific Timeout for WatchDog event + * + * @return WWDT_FUNC_OK if success + **********************************************************************/ +int8_t WWDT_Start(uint32_t TimeOut) +{ + int8_t retval = WWDT_FUNC_OK; + + retval = WWDT_SetTimeOut(TimeOut); + + WWDT_Cmd(ENABLE); + + return retval; +} + + +/********************************************************************//** + * @brief Update WDT timeout value and feed + * + * @param[in] WarnTime time to generate watchdog warning interrupt(us) + * should be in range: 2048 .. 134217728 + * + * @return None + *********************************************************************/ +void WWDT_SetTimerConstant(uint32_t constVal) +{ + LPC_WDT->TC = constVal; +} + + +/*********************************************************************//** + * @brief Enable/Disable WDT function + * + * @param[in] Mode WWDT mode that will be enabled/disabled, should be: + * - WWDT_PROTECT_MODE : protect mode + * - WWDT_RESET_MODE : reset mode + * + * @param[in] NewState new state of protection function, should be: + * - ENABLE: The watchdog reload value can be changed at any time + * - DISABLE: The watchdog reload value can be changed only after + * the counter is below the value of WDWARNINT and WDWINDOW + * + * @return None + **********************************************************************/ +void WWDT_SetMode(uint8_t mode, FunctionalState NewState) +{ + if (mode == WWDT_PROTECT_MODE ) + { + if(NewState == ENABLE) + LPC_WDT->MOD |= WWDT_WDMOD_WDPROTECT; + else + LPC_WDT->MOD &= ~WWDT_WDMOD_WDPROTECT; + } + else if(mode == WWDT_RESET_MODE) + { + if(NewState == ENABLE) + LPC_WDT->MOD |= WWDT_WDMOD_WDRESET; + else + LPC_WDT->MOD &= ~WWDT_WDMOD_WDRESET; + } +} + +/*********************************************************************//** + * @brief Enable/Disable WWDT activity + * + * @param[in] NewState To enable/disable the WatchDog + * + * @return None + **********************************************************************/ +void WWDT_Enable(FunctionalState NewState) +{ + if(NewState == ENABLE) + { + LPC_WDT->MOD |= WWDT_WDMOD_WDEN; + } + else + { + LPC_WDT->MOD &= ~WWDT_WDMOD_WDEN; + } +} + +/*********************************************************************//** + * @brief Enable/Disable WWDT activity. In case of Enable, it will + * do feeding WatchDog for its normal operation. + * + * @param[in] NewState To enable/disable the WatchDog + * + * @return None + **********************************************************************/ +void WWDT_Cmd(FunctionalState NewState) +{ + if(NewState == ENABLE) + { + LPC_WDT->MOD |= WWDT_WDMOD_WDEN; + + //Load the Feed register to start using WDT + WWDT_Feed(); + } + else + { + LPC_WDT->MOD &= ~WWDT_WDMOD_WDEN; + } +} + +/********************************************************************//** + * @brief Set the warning value to register to generate interrupt + * (if enable) if the watchdog timer matches this value. + * + * @param[in] warnVal The value (counter) will write directly to Warning + * Register w/o pre-calc + * + * @return WWDT_FUNC_OK if success + *********************************************************************/ +int8_t WWDT_SetWarningRaw(uint32_t warnVal) +{ + int8_t retval = WWDT_FUNC_OK; + + if(warnVal < WWDT_WARNINT_MIN) + { + warnVal = WWDT_WARNINT_MIN; + retval = WWDT_FUNC_BAD_PARAM; + } + else if (warnVal > WWDT_WARNINT_MAX) + { + warnVal = WWDT_WARNINT_MAX; + retval = WWDT_FUNC_BAD_PARAM; + } + + LPC_WDT->WARNINT = warnVal; + + return retval; +} + +/********************************************************************//** + * @brief Update WDT warning time (cal by usec) to warning register + * + * @param[in] WarnTime The time (usec) to generate watchdog warning + * interrupt should be in range: 2048 .. 8192 + * + * @return WWDT_FUNC_OK if success + *********************************************************************/ +int8_t WWDT_SetWarning(uint32_t WarnTime) +{ + return WWDT_SetWarningRaw(WDT_GET_FROM_USEC(WarnTime)); +} + + +/********************************************************************//** + * @brief Update WDT Windows value (by counter) to Window Register + * of WatchDog + * + * @param[in] wndVal The value (counter) will write directly to Window + * Register w/o pre-calc + * + * @return WWDT_FUNC_OK if success + *********************************************************************/ +int8_t WWDT_SetWindowRaw(uint32_t wndVal) +{ + int8_t retval = WWDT_FUNC_OK; + + if(wndVal < WWDT_WINDOW_MIN) + { + wndVal = WWDT_WINDOW_MIN; + retval = WWDT_FUNC_BAD_PARAM; + } + else if (wndVal > WWDT_WINDOW_MAX) + { + wndVal = WWDT_WINDOW_MAX; + retval = WWDT_FUNC_BAD_PARAM; + } + + LPC_WDT->WINDOW = wndVal; + + return retval; +} + + +/********************************************************************//** + * @brief Update WDT Windows value (by usec) to Window Register + * of WatchDog + * + * @param[in] WindowedTime Expected time (usec) to set watchdog window event + * + * @return WWDT_FUNC_OK if success + *********************************************************************/ +int8_t WWDT_SetWindow(uint32_t WindowedTime) +{ + return WWDT_SetWindowRaw(WDT_GET_FROM_USEC(WindowedTime)); +} + + +/********************************************************************//** + * @brief Update WDT timeout value for WatchDog event(s) + * + * @param[in] TimeOut Time Out value (usec) to be updated, should be + * in range: 2048 .. 134217728 + * + * @return None + *********************************************************************/ +void WDT_UpdateTimeOut(uint32_t TimeOut) +{ + /* check WDPROTECT, + * if it is enable, wait until the counter is below the value of + * WDWARNINT and WDWINDOW + */ + if(LPC_WDT->MOD & (1<<4)) + { + while((LPC_WDT->TV <(LPC_WDT->WARNINT & WWDT_WDWARNINT_MASK))\ + &&(LPC_WDT->TV <(LPC_WDT->WINDOW & WWDT_WDTC_MASK))); + } + + WWDT_SetTimeOut(TimeOut); +} + + +/********************************************************************//** + * @brief Read WWDT status flag + * + * @param[in] Status kind of status flag that you want to get, should be: + * - WWDT_WARNINT_FLAG: watchdog interrupt flag + * - WWDT_TIMEOUT_FLAG: watchdog time-out flag + * + * @return Time out flag status of WDT + *********************************************************************/ +FlagStatus WWDT_GetStatus (uint8_t Status) +{ + if(Status == WWDT_WARNINT_FLAG) + { + return ((FlagStatus)(LPC_WDT->MOD & (1<<3))); + } + else if (Status == WWDT_TIMEOUT_FLAG) + { + return ((FlagStatus)(LPC_WDT->MOD & (1<<2))); + } + return RESET; +} + +/********************************************************************//** + * @brief Clear WWDT status flag + * + * @param[in] Status kind of status flag that you want to get, should be: + * - WWDT_WARNINT_FLAG: watchdog interrupt flag + * - WWDT_TIMEOUT_FLAG: watchdog time-out flag + * + * @return None + *********************************************************************/ +void WWDT_ClearStatusFlag (uint8_t flag) +{ + if(flag == WWDT_WARNINT_FLAG) + { + // Write 1 to this bit to clear itself + LPC_WDT->MOD |= WWDT_WDMOD_WDINT; + } + else if(flag == WWDT_TIMEOUT_FLAG) + { + // Write 0 to this bit to clear itself + LPC_WDT->MOD &= ~ WWDT_WDMOD_WDTOF; + } +} + +/********************************************************************//** + * @brief Clear WDT Time out flag + * @param None + * @return None + *********************************************************************/ +void WWDT_ClrTimeOutFlag (void) +{ + LPC_WDT->MOD &= ~ WWDT_WDMOD_WDTOF; +} + + +/********************************************************************//** + * @brief Following the standard sequence to Feed the WatchDog Timer + * + * @param None + * + * @return None + *********************************************************************/ +void WWDT_FeedStdSeq (void) +{ + LPC_WDT->FEED = 0xAA; + + LPC_WDT->FEED = 0x55; +} + +/********************************************************************//** + * @brief After set WDTEN, call this function to start Watchdog + * or reload the Watchdog timer + * + * @param None + * + * @return None + *********************************************************************/ +void WWDT_Feed (void) +{ + // Disable irq interrupt + __disable_irq(); + + WWDT_FeedStdSeq(); + + // Then enable irq interrupt + __enable_irq(); +} + +/********************************************************************//** + * @brief Get the current value of WDT + * + * @param None + * + * @return Current value of WDT + *********************************************************************/ +uint32_t WWDT_GetCurrentCount(void) +{ + return LPC_WDT->TV; +} + +/** + * @} + */ + +#endif /*_WDT*/ +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ diff --git a/bsp/lpc408x/Libraries/Drivers/source/makefile b/bsp/lpc408x/Libraries/Drivers/source/makefile new file mode 100644 index 0000000000000000000000000000000000000000..75cb107193e6573dea6ac04b11c9181cfab2db5c --- /dev/null +++ b/bsp/lpc408x/Libraries/Drivers/source/makefile @@ -0,0 +1,91 @@ +######################################################################## +# $Id:: makefile 814 2008-06-19 19:57:32Z pdurgesh $ +# +# Project: Standard compile makefile +# +# Description: +# Makefile +# +######################################################################## +# Software that is described herein is for illustrative purposes only +# which provides customers with programming information regarding the +# products. This software is supplied "AS IS" without any warranties. +# NXP Semiconductors assumes no responsibility or liability for the +# use of the software, conveys no license or title under any patent, +# copyright, or mask work right to the product. NXP Semiconductors +# reserves the right to make changes in the software without +# notification. NXP Semiconductors also make no representation or +# warranty that such application will be suitable for the specified +# use without further testing or modification. +######################################################################## + +######################################################################## +# +# Get the project root +# +######################################################################## +PROJ_ROOT = $(CURDIR)/../.. + +######################################################################## +# +# Pick up the configuration file in make section +# +######################################################################## +include ../../makesection/makeconfig + +######################################################################## +# +# Pick up the default build rules +# +######################################################################## + +include $(PROJ_ROOT)/makesection/makerule/LPC/make.LPC.$(TOOL) + +######################################################################## +# +# Pick up the assembler and C source files in the directory +# +######################################################################## +include $(PROJ_ROOT)/makesection/makerule/common/make.rules.ftypes +AFLAGS +=-I../include +CFLAGS +=-I../include + + +######################################################################## +# +# Build the library +# +######################################################################## + +$(TARGET_FWLIB_LIB) : .vias $(OBJS) $(FWLIB_LIB_DIR) + $(ECHO) "creating" $(FWLIB) "Firmware support package library" + $(AR) $@ $(OBJS) + +$(FWLIB_LIB_DIR): + $(MKDIR) $(FWLIB_LIB_DIR) + +# delete all targets this Makefile can make +lib_clean: + -@$(RM) $(TARGET_FWLIB_LIB) + +# delete all targets this Makefile can make and all built libraries +# linked in +lib_realclean: + -@$(RM) $(FWLIB_LIB_DIR)/*.a + -@$(RMDIR) $(FWLIB_LIB_DIR) + +clean: lib_clean +realclean: lib_realclean + +######################################################################## +# +# Compile the code base +# +######################################################################## + +include $(PROJ_ROOT)/makesection/makerule/common/make.rules.build + +.PHONY: all lib_clean lib_realclean + + + diff --git a/bsp/lpc408x/Libraries/SConscript b/bsp/lpc408x/Libraries/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..4c815c49b835a3a5ea61f337dc17154dd316d7d1 --- /dev/null +++ b/bsp/lpc408x/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/lpc408x/SConscript b/bsp/lpc408x/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..381b1612c717a6aff6ebf99434da07ca16fce99b --- /dev/null +++ b/bsp/lpc408x/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/lpc408x/SConstruct b/bsp/lpc408x/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..5ee8731aea2839b9a7260e17e14784a7c2d53280 --- /dev/null +++ b/bsp/lpc408x/SConstruct @@ -0,0 +1,29 @@ +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, + 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/lpc408x/applications/SConscript b/bsp/lpc408x/applications/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..01eb940dfb35f92c503a78b0b49a4354590f9f3a --- /dev/null +++ b/bsp/lpc408x/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/lpc408x/applications/application.c b/bsp/lpc408x/applications/application.c new file mode 100644 index 0000000000000000000000000000000000000000..854777b1fb7c24576fcb27c3334ca418f74dcd30 --- /dev/null +++ b/bsp/lpc408x/applications/application.c @@ -0,0 +1,45 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2014, 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 + * 2014-01-02 xiaonong the first version for lpc408x + */ + +#include + +#include +#include + + +/* thread phase init */ +void rt_init_thread_entry(void *parameter) +{ + /* Initialization RT-Thread Components */ +#ifdef RT_USING_COMPONENTS_INIT + rt_components_init(); +#endif + +#ifdef RT_USING_FINSH + /* initialize finsh */ + finsh_system_init(); + finsh_set_device(FINSH_DEVICE_NAME); +#endif +} + +int rt_application_init(void) +{ + 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/lpc408x/applications/board.c b/bsp/lpc408x/applications/board.c new file mode 100644 index 0000000000000000000000000000000000000000..d703b1583e9d0ec038de26497e80ea8e3f64f441 --- /dev/null +++ b/bsp/lpc408x/applications/board.c @@ -0,0 +1,68 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first implementation + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" +#ifdef LPC_EXT_SDRAM +#include "drv_sdram.h" +#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 LPC40xx 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 + + /* init systick */ + 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); + +#ifdef LPC_EXT_SDRAM + rt_kprintf("Initialize SDRAM ..."); + lpc_sdram_hw_init(); + rt_kprintf("done!\n"); +#endif + +} diff --git a/bsp/lpc408x/applications/board.h b/bsp/lpc408x/applications/board.h new file mode 100644 index 0000000000000000000000000000000000000000..f34cb2acee707a289cc37378f36a4010c4ae238c --- /dev/null +++ b/bsp/lpc408x/applications/board.h @@ -0,0 +1,55 @@ +/* + * 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 + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "LPC407x_8x_177x_8x.h" +#include + +// + +// +//#define LPC_EXT_SDRAM 0 +// +#define LPC_EXT_SDRAM_BEGIN 0xA0000000 +// +#define LPC_EXT_SDRAM_END 0xA2000000 + +// +#define RT_USING_UART0 +// +//#define RT_USING_UART1 +// +#define RT_USING_UART2 + +// + +#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 (0x10000000 + 0x10000) + +#define FINSH_DEVICE_NAME RT_CONSOLE_DEVICE_NAME +void rt_hw_board_init(void); + +#endif diff --git a/bsp/lpc408x/applications/sram.c b/bsp/lpc408x/applications/sram.c new file mode 100644 index 0000000000000000000000000000000000000000..e7ac0fe1585c073e79591d0fd879002620b4b968 --- /dev/null +++ b/bsp/lpc408x/applications/sram.c @@ -0,0 +1,47 @@ +/* +* File : sram.c +* This file is part of RT-Thread RTOS +* COPYRIGHT (C) 2009-2013 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-19 Bernard The first version for LPC40xx +*/ + +#include "sram.h" +#include "board.h" + +#include + +#ifdef LPC_EXT_SDRAM +struct rt_memheap system_heap; + +void sram_init(void) +{ + /* initialize the built-in SRAM as a memory heap */ + rt_memheap_init(&system_heap, + "system", + (void *)HEAP_BEGIN, + (rt_uint32_t)HEAP_END - (rt_uint32_t)HEAP_BEGIN); +} + +void *sram_malloc(unsigned long size) +{ + return rt_memheap_alloc(&system_heap, size); +} + +void sram_free(void *ptr) +{ + rt_memheap_free(ptr); +} + +void *sram_realloc(void *ptr, unsigned long size) +{ + return rt_memheap_realloc(&system_heap, ptr, size); +} + +#endif diff --git a/bsp/lpc408x/applications/sram.h b/bsp/lpc408x/applications/sram.h new file mode 100644 index 0000000000000000000000000000000000000000..902337aafc6abec044dac048961805291e47b242 --- /dev/null +++ b/bsp/lpc408x/applications/sram.h @@ -0,0 +1,22 @@ +/* + * File : sram.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009-2013 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-19 Bernard The first version for LPC40xx + */ + +#ifndef __SRAM_H__ +#define __SRAM_H__ + +void *sram_malloc(unsigned long nbytes); +void sram_free(void *ptr); +void *sram_realloc(void *ptr, unsigned long nbytes); + +#endif diff --git a/bsp/lpc408x/applications/startup.c b/bsp/lpc408x/applications/startup.c new file mode 100644 index 0000000000000000000000000000000000000000..67df608698947235b5f958837b0d73c656027e89 --- /dev/null +++ b/bsp/lpc408x/applications/startup.c @@ -0,0 +1,72 @@ +/* + * File : startup.c + * 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-01-05 Bernard first implementation + * 2010-03-04 Magicoe for LPC17xx + */ + +#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(); + +#ifdef RT_USING_HEAP +#if LPC_EXT_SDRAM + 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 + + /* initialize scheduler system */ + rt_system_scheduler_init(); + /* initialize system timer*/ + rt_system_timer_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/lpc408x/drivers/SConscript b/bsp/lpc408x/drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..e5f4cd494566242fd5f19e775ccff2a69e43d2ac --- /dev/null +++ b/bsp/lpc408x/drivers/SConscript @@ -0,0 +1,14 @@ +from building import * + +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/lpc408x/drivers/drv_led.c b/bsp/lpc408x/drivers/drv_led.c new file mode 100644 index 0000000000000000000000000000000000000000..f9cc5e602f9e932c9f78ba8042edd7e5e2efef4d --- /dev/null +++ b/bsp/lpc408x/drivers/drv_led.c @@ -0,0 +1,144 @@ +#include +#include "board.h" + +#define RT_DEVICE_CTRL_RTC_GET_COUNT 0x81 /**< get count */ + +#define LED_NUM 4 +struct led_ctrl +{ + uint32_t num; + LPC_GPIO_TypeDef *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) +{ + /* led0 : P4.14,led1:P4.15 ,led2:P4.16 ,led3:P4.17*/ + /* set P4.14,P4.15,P4.16,P4.17 as GPIO. */ + LPC_IOCON->P4_14 = 0x00; + LPC_IOCON->P4_15 = 0x00; + LPC_IOCON->P4_16 = 0x00; + LPC_IOCON->P4_17 = 0x00; + /* set P4.14,P4.15,P4.16,P4.17 output. */ + LPC_GPIO4->DIR |= (0x0f << 14); + /* turn off all the led */ + LPC_GPIO4->SET = (0x0f << 14); + led.ctrl[0].num = 14; + led.ctrl[0].port = LPC_GPIO4; + led.ctrl[1].num = 15; + led.ctrl[1].port = LPC_GPIO4; + led.ctrl[2].num = 16; + led.ctrl[2].port = LPC_GPIO4; + led.ctrl[3].num = 17; + led.ctrl[3].port = LPC_GPIO4; + 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 ((led.ctrl[pos + index].port->PIN) & 1 << 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++) + { + led.ctrl[pos + index].port->CLR |= (1 << led.ctrl[pos + index].num); + } + else + { + led.ctrl[pos + index].port->SET |= (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) +{ + RT_ASSERT(dev == &led.parent); + + if (cmd == RT_DEVICE_CTRL_RTC_GET_COUNT) + { + rt_uint32_t *led_num = args; + *led_num = LED_NUM; + } + return RT_EOK; +} + +void 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); +} + +#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/lpc408x/drivers/drv_led.h b/bsp/lpc408x/drivers/drv_led.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/bsp/lpc408x/drivers/drv_uart.c b/bsp/lpc408x/drivers/drv_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..37213c0474a635eff539c809686a1e77c973c381 --- /dev/null +++ b/bsp/lpc408x/drivers/drv_uart.c @@ -0,0 +1,286 @@ +/* + * File : drv_uart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009-2013 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 + */ + +#include +#include +#include + +#include "board.h" +#include "lpc_uart.h" +#include "lpc_pinsel.h" + +struct lpc_uart +{ + UART_ID_Type 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_CFG_Type UARTConfigStruct; + UART_FIFO_CFG_Type UARTFIFOConfigStruct; + + RT_ASSERT(serial != RT_NULL); + uart = (struct lpc_uart *)serial->parent.user_data; + + /* Initialize UART Configuration parameter structure to default state: + * Baudrate = 115200 bps + * 8 data bit + * 1 Stop bit + * None parity + */ + UART_ConfigStructInit(&UARTConfigStruct); + UARTConfigStruct.Baud_rate = 115200; + + // Initialize UART0 peripheral with given to corresponding parameter + UART_Init(uart->UART, &UARTConfigStruct); + + /* Initialize FIFOConfigStruct to default state: + * - FIFO_DMAMode = DISABLE + * - FIFO_Level = UART_FIFO_TRGLEV0 + * - FIFO_ResetRxBuf = ENABLE + * - FIFO_ResetTxBuf = ENABLE + * - FIFO_State = ENABLE + */ + UART_FIFOConfigStructInit(&UARTFIFOConfigStruct); + + // Initialize FIFO for UART0 peripheral + UART_FIFOConfig(uart->UART, &UARTFIFOConfigStruct); + + UART_TxCmd(uart->UART, ENABLE); + + 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_IntConfig(uart->UART, UART_INTCFG_RBR, DISABLE); + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + UART_IntConfig(uart->UART, UART_INTCFG_RBR, ENABLE); + 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; + UART_Send(uart->UART, (uint8_t *)&c, 1, BLOCKING); + + return 1; +} + +static int lpc_getc(struct rt_serial_device *serial) +{ + uint8_t ch; + struct lpc_uart *uart; + + uart = (struct lpc_uart *)serial->parent.user_data; + if (UART_Receive(uart->UART, &ch, 1, NONE_BLOCKING) == 1) + return (int) ch; + + return -1; +} + +static const struct rt_uart_ops lpc_uart_ops = +{ + lpc_configure, + lpc_control, + lpc_putc, + lpc_getc, +}; + +#if defined(RT_USING_UART0) +/* UART0 device driver structure */ +struct serial_ringbuffer uart0_int_rx; +struct lpc_uart uart0 = +{ + UART_0, + UART0_IRQn, +}; +struct rt_serial_device serial0; + +void UART0_IRQHandler(void) +{ + struct lpc_uart *uart; + uint32_t intsrc, tmp, tmp1; + + uart = &uart0; + + /* enter interrupt */ + rt_interrupt_enter(); + + /* Determine the interrupt source */ + intsrc = UART_GetIntId(uart->UART); + tmp = intsrc & UART_IIR_INTID_MASK; + + // Receive Line Status + if (tmp == UART_IIR_INTID_RLS) + { + // Check line status + tmp1 = UART_GetLineStatus(uart->UART); + // Mask out the Receive Ready and Transmit Holding empty status + tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \ + | UART_LSR_BI | UART_LSR_RXFE); + // If any error exist + if (tmp1) + { + // + } + } + + // Receive Data Available or Character time-out + if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)) + { + rt_hw_serial_isr(&serial0); + } + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#if defined(RT_USING_UART2) +/* UART2 device driver structure */ +struct serial_ringbuffer uart2_int_rx; +struct lpc_uart uart2 = +{ + UART_2, + UART2_IRQn, +}; +struct rt_serial_device serial2; + +void UART2_IRQHandler(void) +{ + struct lpc_uart *uart; + uint32_t intsrc, tmp, tmp1; + + uart = &uart2; + + /* enter interrupt */ + rt_interrupt_enter(); + + /* Determine the interrupt source */ + intsrc = UART_GetIntId(uart->UART); + tmp = intsrc & UART_IIR_INTID_MASK; + + // Receive Line Status + if (tmp == UART_IIR_INTID_RLS) + { + // Check line status + tmp1 = UART_GetLineStatus(uart->UART); + // Mask out the Receive Ready and Transmit Holding empty status + tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \ + | UART_LSR_BI | UART_LSR_RXFE); + // If any error exist + if (tmp1) + { + // + } + } + + // Receive Data Available or Character time-out + if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)) + { + rt_hw_serial_isr(&serial2); + } + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +void rt_hw_uart_init(void) +{ + struct lpc_uart *uart; + struct serial_configure config; + +#ifdef RT_USING_UART0 + uart = &uart0; + config.baud_rate = BAUD_RATE_115200; + config.bit_order = BIT_ORDER_LSB; + config.data_bits = DATA_BITS_8; + config.parity = PARITY_NONE; + config.stop_bits = STOP_BITS_1; + config.invert = NRZ_NORMAL; + + serial0.ops = &lpc_uart_ops; + serial0.int_rx = &uart0_int_rx; + serial0.config = config; + + /* + * Initialize UART0 pin connect + * P0.2: U0_TXD + * P0.3: U0_RXD + */ + PINSEL_ConfigPin(0, 2, 1); + PINSEL_ConfigPin(0, 3, 1); + + /* preemption = 1, sub-priority = 1 */ + NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01)); + + /* Enable Interrupt for UART channel */ + NVIC_EnableIRQ(uart->UART_IRQn); + + /* register UART1 device */ + rt_hw_serial_register(&serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + uart); +#endif +#ifdef RT_USING_UART2 + uart = &uart2; + config.baud_rate = BAUD_RATE_115200; + config.bit_order = BIT_ORDER_LSB; + config.data_bits = DATA_BITS_8; + config.parity = PARITY_NONE; + config.stop_bits = STOP_BITS_1; + config.invert = NRZ_NORMAL; + + serial2.ops = &lpc_uart_ops; + serial2.int_rx = &uart2_int_rx; + serial2.config = config; + + /* + * Initialize UART2 pin connect + * P2.8: U2_TXD + * P0.11: U2_RXD + */ + PINSEL_ConfigPin(2, 8, 2); + PINSEL_ConfigPin(0, 11, 1); + + /* preemption = 1, sub-priority = 1 */ + NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01)); + + /* Enable Interrupt for UART channel */ + NVIC_EnableIRQ(uart->UART_IRQn); + + /* register UART1 device */ + rt_hw_serial_register(&serial2, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + uart); +#endif +} diff --git a/bsp/lpc408x/drivers/drv_uart.h b/bsp/lpc408x/drivers/drv_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..c5ca6c70c4724bc64a5e950a5a2b39f4a2d6a8ab --- /dev/null +++ b/bsp/lpc408x/drivers/drv_uart.h @@ -0,0 +1,6 @@ +#ifndef __UART_H__ +#define __UART_H__ + +void rt_hw_uart_init(void); + +#endif diff --git a/bsp/lpc408x/rtconfig.h b/bsp/lpc408x/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..23f4e757c34ba3ce39b9eac56f33373021403c52 --- /dev/null +++ b/bsp/lpc408x/rtconfig.h @@ -0,0 +1,240 @@ +/* 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 IDLE_THREAD_STACK_SIZE 512 +// +//#define RT_USING_MODULE +//
+#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 100 +//
+ +//
+// +#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_UART_RX_BUFFER_SIZE 64 +//
+// +//#define RT_USING_SPI +// +//#define RT_USING_I2C +// +//#define RT_USING_RTC +// +#define RT_MMCSD_THREAD_PREORITY 15 +//
+#define RT_USING_CONSOLE +// +#define RT_CONSOLEBUF_SIZE 128 +// +#define RT_CONSOLE_DEVICE_NAME "uart0" +//
+ +// +#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 16 +// +#define RT_USING_DFS_ELMFAT +// +#define RT_DFS_ELM_DRIVES 2 +// +#define RT_DFS_ELM_REENTRANT +// +// 1 +// 2 +// 3 +// +#define RT_DFS_ELM_USE_LFN 3 +// +#define RT_DFS_ELM_CODE_PAGE 936 +// +#define RT_DFS_ELM_CODE_PAGE_FILE +// +#define RT_DFS_ELM_MAX_LFN 256 +// +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +// +// #define RT_USING_DFS_YAFFS2 +// +// #define RT_USING_DFS_UFFS +// +#define RT_USING_DFS_DEVFS +// +//#define RT_USING_DFS_ROMFS +//
+ +//
+//#define RT_USING_LWIP +// +#define RT_USING_LWIP141 +// +#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 4086 +// +#define RT_LWIP_TCP_WND 2048 +// +// #define RT_LWIP_SNMP +// +// #define RT_LWIP_DHCP +// +#define RT_LWIP_TCP_SEG_NUM 4 +// +#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 +/* image support */ +//#define RTGUI_IMAGE_XPM +//#define RTGUI_IMAGE_BMP +/* #define RTGUI_IMAGE_JPEG */ +/* #define RTGUI_IMAGE_PNG */ +//#define RTGUI_USING_NOTEBOOK_IMAGE +//
+ +//
+ +#endif diff --git a/bsp/lpc408x/rtconfig.py b/bsp/lpc408x/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..4d97373f4e924fa7bd5a09c07084acc55d17c986 --- /dev/null +++ b/bsp/lpc408x/rtconfig.py @@ -0,0 +1,82 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='keil' +BOARD_NAME = 'lpc408x' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'D:/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'D:/Keil' +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' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -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' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-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' + + 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/lpc408x/rtthread-lpc408x.ld b/bsp/lpc408x/rtthread-lpc408x.ld new file mode 100644 index 0000000000000000000000000000000000000000..021d51a5043f8cfb6c5d52beeecde416b4be1333 --- /dev/null +++ b/bsp/lpc408x/rtthread-lpc408x.ld @@ -0,0 +1,133 @@ +/* + * linker script for LPC1788 (512kB Flash, 48kB + 48kB SRAM ) with GNU ld + * yiyue.fang 2012-04-14 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + DATA (rw) : ORIGIN = 0x10000000, LENGTH = 0x00010000 +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + KEEP(*(.interrupt_vector)) /* Startup code */ + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + *(.bss.init) + } > DATA + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/lpc408x/rtthread-lpc408x.sct b/bsp/lpc408x/rtthread-lpc408x.sct new file mode 100644 index 0000000000000000000000000000000000000000..893f49ce4ad7886d6787ec9a669482f9a8974df3 --- /dev/null +++ b/bsp/lpc408x/rtthread-lpc408x.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 0x10000000 0x00010000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/lpc408x/template.uvproj b/bsp/lpc408x/template.uvproj new file mode 100644 index 0000000000000000000000000000000000000000..68d0e0934d60b4a5e07050e8e6ffd16f327465a1 --- /dev/null +++ b/bsp/lpc408x/template.uvproj @@ -0,0 +1,394 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + RT-Thread LPC408x + 0x4 + ARM-ADS + + + LPC4088 + NXP (founded by Philips) + IRAM(0x10000000-0x1000FFFF) IRAM2(0x20000000-0x20007FFF) IROM(0-0x7FFFF) CLOCK(12000000) CPUTYPE("Cortex-M4") FPU2 + + "STARTUP\NXP\LPC407x_8x_177x_8x\startup_LPC407x_8x_177x_8x.s" ("NXP LPC407x_8x_177x_8x Startup Code") + UL2CM3(-O4303 -S0 -C0 -FO7 -FD10000000 -FC800 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000) + 6493 + LPC407x_8x_177x_8x.h + + + + + + + + + + SFD\NXP\LPC407x_8x_177x_8x\LPC408x_7x.SFR + 0 + + + + NXP\LPC407x_8x_177x_8x\ + NXP\LPC407x_8x_177x_8x\ + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-lpc + 1 + 0 + 0 + 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 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + + 0 + 7 + + + + + + + + + + + + + + Segger\JL2CM3.dll + + + + + 1 + 0 + 0 + 0 + 1 + 4099 + + 0 + Segger\JL2CM3.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 + 0x10000000 + 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 + 0x10000000 + 0x10000 + + + 0 + 0x20000000 + 0x8000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x10000000 + + + + + + + + + + + + +